From b328b08d70ec5fc60ac0b542790698f7d8110cd4 Mon Sep 17 00:00:00 2001 From: "icyphox.sh" Date: Mon, 7 Apr 2025 16:52:59 +0000 Subject: [PATCH] appview: pages/blob: toggle render for markdown files Also sets up a pages/markup package with extensible rendering for future markup languages that we may support. We may also want an interface or something for markup.RenderMarkdown (maybe just markup.Render), but don't have to bother with that now. --- appview/pages/funcmap.go | 3 ++- appview/pages/{ => markup}/markdown.go | 5 +++-- appview/pages/markup/readme.go | 26 ++++++++++++++++++++++++++ appview/pages/pages.go | 20 +++++++++++++++----- appview/pages/templates/repo/blob.html | 11 ++++++++++- appview/state/repo.go | 11 +++++++++++ 6 files changed, 67 insertions(+), 9 deletions(-) rename appview/pages/{ => markup}/markdown.go (73%) create mode 100644 appview/pages/markup/readme.go diff --git a/appview/pages/funcmap.go b/appview/pages/funcmap.go index 775006a0..8d886046 100644 --- a/appview/pages/funcmap.go +++ b/appview/pages/funcmap.go @@ -13,6 +13,7 @@ import ( "time" "github.com/dustin/go-humanize" + "tangled.sh/tangled.sh/core/appview/pages/markup" ) func funcMap() template.FuncMap { @@ -137,7 +138,7 @@ func funcMap() template.FuncMap { return v.Slice(start, end).Interface() }, "markdown": func(text string) template.HTML { - return template.HTML(renderMarkdown(text)) + return template.HTML(markup.RenderMarkdown(text)) }, "isNil": func(t any) bool { // returns false for other "zero" values diff --git a/appview/pages/markdown.go b/appview/pages/markup/markdown.go similarity index 73% rename from appview/pages/markdown.go rename to appview/pages/markup/markdown.go index d27d9060..a219f3d7 100644 --- a/appview/pages/markdown.go +++ b/appview/pages/markup/markdown.go @@ -1,4 +1,5 @@ -package pages +// Package markup is an umbrella package for all markups and their renderers. +package markup import ( "bytes" @@ -8,7 +9,7 @@ import ( "github.com/yuin/goldmark/parser" ) -func renderMarkdown(source string) string { +func RenderMarkdown(source string) string { md := goldmark.New( goldmark.WithExtensions(extension.GFM), goldmark.WithParserOptions( diff --git a/appview/pages/markup/readme.go b/appview/pages/markup/readme.go new file mode 100644 index 00000000..5b104c7d --- /dev/null +++ b/appview/pages/markup/readme.go @@ -0,0 +1,26 @@ +package markup + +import "strings" + +type Format string + +const ( + FormatMarkdown Format = "markdown" + FormatText Format = "text" +) + +var FileTypes map[Format][]string = map[Format][]string{ + FormatMarkdown: []string{".md", ".markdown", ".mdown", ".mkdn", ".mkd"}, +} + +func GetFormat(filename string) Format { + for format, extensions := range FileTypes { + for _, extension := range extensions { + if strings.HasSuffix(filename, extension) { + return format + } + } + } + // default format + return FormatText +} diff --git a/appview/pages/pages.go b/appview/pages/pages.go index a2a19aff..f6d28db2 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -24,6 +24,7 @@ import ( "github.com/microcosm-cc/bluemonday" "tangled.sh/tangled.sh/core/appview/auth" "tangled.sh/tangled.sh/core/appview/db" + "tangled.sh/tangled.sh/core/appview/pages/markup" "tangled.sh/tangled.sh/core/appview/state/userutil" "tangled.sh/tangled.sh/core/types" ) @@ -350,7 +351,7 @@ func (p *Pages) RepoIndexPage(w io.Writer, params RepoIndexParams) error { ext := filepath.Ext(params.ReadmeFileName) switch ext { case ".md", ".markdown", ".mdown", ".mkdn", ".mkd": - htmlString = renderMarkdown(params.Readme) + htmlString = markup.RenderMarkdown(params.Readme) params.Raw = false params.HTMLReadme = template.HTML(bluemonday.UGCPolicy().Sanitize(htmlString)) default: @@ -446,10 +447,12 @@ func (p *Pages) RepoTags(w io.Writer, params RepoTagsParams) error { } type RepoBlobParams struct { - LoggedInUser *auth.User - RepoInfo RepoInfo - Active string - BreadCrumbs [][]string + LoggedInUser *auth.User + RepoInfo RepoInfo + Active string + BreadCrumbs [][]string + ShowRendered bool + RenderedContents template.HTML types.RepoBlobResponse } @@ -459,6 +462,13 @@ func (p *Pages) RepoBlob(w io.Writer, params RepoBlobParams) error { b.Add(chroma.LiteralString, "noitalic") style, _ = b.Build() + if params.ShowRendered { + switch markup.GetFormat(params.Path) { + case markup.FormatMarkdown: + params.RenderedContents = template.HTML(markup.RenderMarkdown(params.Contents)) + } + } + if params.Lines < 5000 { c := params.Contents formatter := chromahtml.New( diff --git a/appview/pages/templates/repo/blob.html b/appview/pages/templates/repo/blob.html index 6736c712..4d456aae 100644 --- a/appview/pages/templates/repo/blob.html +++ b/appview/pages/templates/repo/blob.html @@ -43,6 +43,11 @@ {{ byteFmt .SizeHint }} view raw + + view {{ if .ShowRendered }}code{{ else }}rendered{{ end }} @@ -52,7 +57,11 @@

{{ else }}
-
{{ $.Contents | escapeHtml }}
+ {{ if .ShowRendered }} +
{{ .RenderedContents }}
+ {{ else }} +
{{ $.Contents | escapeHtml }}
+ {{ end }}
{{ end }} {{ end }} diff --git a/appview/state/repo.go b/appview/state/repo.go index 40b10ee8..b756477c 100644 --- a/appview/state/repo.go +++ b/appview/state/repo.go @@ -25,6 +25,7 @@ import ( "tangled.sh/tangled.sh/core/appview/auth" "tangled.sh/tangled.sh/core/appview/db" "tangled.sh/tangled.sh/core/appview/pages" + "tangled.sh/tangled.sh/core/appview/pages/markup" "tangled.sh/tangled.sh/core/types" comatproto "github.com/bluesky-social/indigo/api/atproto" @@ -453,12 +454,22 @@ func (s *State) RepoBlob(w http.ResponseWriter, r *http.Request) { } } + var showRendered = false + if markup.GetFormat(result.Path) == markup.FormatMarkdown { + showRendered = true + } + + if r.URL.Query().Get("code") == "true" { + showRendered = false + } + user := s.auth.GetUser(r) s.pages.RepoBlob(w, pages.RepoBlobParams{ LoggedInUser: user, RepoInfo: f.RepoInfo(s, user), RepoBlobResponse: result, BreadCrumbs: breadcrumbs, + ShowRendered: showRendered, }) return } -- 2.54.0