mirror of
https://github.com/charmbracelet/glow.git
synced 2026-08-23 00:24:17 +02:00
Merge 6cb86a1338 into 53788271b3
This commit is contained in:
commit
9dfbd6c922
4 changed files with 95 additions and 9 deletions
|
|
@ -49,7 +49,7 @@ func findGitHubREADME(u *url.URL) (*source, error) {
|
|||
}
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return &source{resp.Body, result.DownloadURL}, nil
|
||||
return &source{reader: resp.Body, URL: result.DownloadURL}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func findGitLabREADME(u *url.URL) (*source, error) {
|
|||
}
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return &source{resp.Body, readmeRawURL}, nil
|
||||
return &source{reader: resp.Body, URL: readmeRawURL}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
53
glow_test.go
53
glow_test.go
|
|
@ -1,6 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -39,3 +42,53 @@ func TestGlowFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceDetectsExtensionlessJSONContentType(t *testing.T) {
|
||||
src := source{
|
||||
URL: "https://api.example.com/endpoint",
|
||||
contentType: "application/vnd.api+json; charset=utf-8",
|
||||
}
|
||||
|
||||
if !src.isCode() {
|
||||
t.Fatal("expected extensionless JSON response to render as code")
|
||||
}
|
||||
if got := src.codeBlockLanguage(); got != ".json" {
|
||||
t.Fatalf("expected .json code block language, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceMarkdownExtensionTakesPrecedenceOverContentType(t *testing.T) {
|
||||
src := source{
|
||||
URL: "https://example.com/README.md",
|
||||
contentType: "application/json",
|
||||
}
|
||||
|
||||
if src.isCode() {
|
||||
t.Fatal("expected markdown extension to render as markdown")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceFromArgRecordsHTTPContentType(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
fmt.Fprint(w, `{"ok":true}`)
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
src, err := sourceFromArg(server.URL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if err := src.reader.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
if got := src.contentType; got != "application/json; charset=utf-8" {
|
||||
t.Fatalf("expected content type to be recorded, got %q", got)
|
||||
}
|
||||
if !src.isCode() {
|
||||
t.Fatal("expected extensionless JSON HTTP source to render as code")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
47
main.go
47
main.go
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
|
@ -67,8 +68,9 @@ var (
|
|||
|
||||
// source provides a readable markdown source.
|
||||
type source struct {
|
||||
reader io.ReadCloser
|
||||
URL string
|
||||
reader io.ReadCloser
|
||||
URL string
|
||||
contentType string
|
||||
}
|
||||
|
||||
// sourceFromArg parses an argument and creates a readable source for it.
|
||||
|
|
@ -99,7 +101,11 @@ func sourceFromArg(arg string) (*source, error) {
|
|||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("HTTP status %d", resp.StatusCode)
|
||||
}
|
||||
return &source{resp.Body, u.String()}, nil
|
||||
return &source{
|
||||
reader: resp.Body,
|
||||
URL: u.String(),
|
||||
contentType: resp.Header.Get("Content-Type"),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +129,7 @@ func sourceFromArg(arg string) (*source, error) {
|
|||
}
|
||||
|
||||
u, _ := filepath.Abs(path)
|
||||
src = &source{r, u}
|
||||
src = &source{reader: r, URL: u}
|
||||
|
||||
// abort filepath.Walk
|
||||
return errors.New("source found")
|
||||
|
|
@ -147,7 +153,34 @@ func sourceFromArg(arg string) (*source, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get absolute path: %w", err)
|
||||
}
|
||||
return &source{r, u}, nil
|
||||
return &source{reader: r, URL: u}, nil
|
||||
}
|
||||
|
||||
func (s source) isCode() bool {
|
||||
if !utils.IsMarkdownFile(s.URL) {
|
||||
return true
|
||||
}
|
||||
return filepath.Ext(s.URL) == "" && s.codeBlockLanguage() != ""
|
||||
}
|
||||
|
||||
func (s source) codeBlockLanguage() string {
|
||||
if ext := filepath.Ext(s.URL); ext != "" {
|
||||
return ext
|
||||
}
|
||||
return codeBlockLanguageFromContentType(s.contentType)
|
||||
}
|
||||
|
||||
func codeBlockLanguageFromContentType(contentType string) string {
|
||||
mediaType, _, err := mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
mediaType = strings.TrimSpace(strings.Split(contentType, ";")[0])
|
||||
}
|
||||
mediaType = strings.ToLower(mediaType)
|
||||
|
||||
if mediaType == "application/json" || strings.HasSuffix(mediaType, "+json") {
|
||||
return ".json"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// validateStyle checks if the style is a default style, if not, checks that
|
||||
|
|
@ -288,7 +321,7 @@ func executeCLI(cmd *cobra.Command, src *source, w io.Writer) error {
|
|||
baseURL = u.String() + "/"
|
||||
}
|
||||
|
||||
isCode := !utils.IsMarkdownFile(src.URL)
|
||||
isCode := src.isCode()
|
||||
|
||||
// initialize glamour
|
||||
r, err := glamour.NewTermRenderer(
|
||||
|
|
@ -303,7 +336,7 @@ func executeCLI(cmd *cobra.Command, src *source, w io.Writer) error {
|
|||
}
|
||||
|
||||
content := string(b)
|
||||
ext := filepath.Ext(src.URL)
|
||||
ext := src.codeBlockLanguage()
|
||||
if isCode {
|
||||
content = utils.WrapCodeBlock(string(b), ext)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue