Monorepo for Tangled tangled.org

wip: render markdown subset in issue/PR titles

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li d499aa0f dfc91bcd

verified
Changed files
+39 -11
appview
+10 -4
appview/pages/funcmap.go
··· 19 20 "github.com/dustin/go-humanize" 21 "github.com/go-enry/go-enry/v2" 22 - "github.com/microcosm-cc/bluemonday" 23 "tangled.sh/tangled.sh/core/appview/filetree" 24 "tangled.sh/tangled.sh/core/appview/pages/markup" 25 ) ··· 207 } 208 return v.Slice(0, min(n, v.Len())).Interface() 209 }, 210 - 211 "markdown": func(text string) template.HTML { 212 - rctx := &markup.RenderContext{RendererType: markup.RendererTypeDefault} 213 - return template.HTML(bluemonday.UGCPolicy().Sanitize(rctx.RenderMarkdown(text))) 214 }, 215 "isNil": func(t any) bool { 216 // returns false for other "zero" values
··· 19 20 "github.com/dustin/go-humanize" 21 "github.com/go-enry/go-enry/v2" 22 "tangled.sh/tangled.sh/core/appview/filetree" 23 "tangled.sh/tangled.sh/core/appview/pages/markup" 24 ) ··· 206 } 207 return v.Slice(0, min(n, v.Len())).Interface() 208 }, 209 "markdown": func(text string) template.HTML { 210 + p.rctx.RendererType = markup.RendererTypeDefault 211 + htmlString := p.rctx.RenderMarkdown(text) 212 + sanitized := p.rctx.SanitizeDefault(htmlString) 213 + return template.HTML(sanitized) 214 + }, 215 + "description": func(text string) template.HTML { 216 + p.rctx.RendererType = markup.RendererTypeDefault 217 + htmlString := p.rctx.RenderMarkdown(text) 218 + sanitized := p.rctx.SanitizeDescription(htmlString) 219 + return template.HTML(sanitized) 220 }, 221 "isNil": func(t any) bool { 222 // returns false for other "zero" values
+4
appview/pages/markup/markdown.go
··· 164 return rctx.Sanitizer.defaultPolicy.Sanitize(html) 165 } 166 167 type MarkdownTransformer struct { 168 rctx *RenderContext 169 }
··· 164 return rctx.Sanitizer.defaultPolicy.Sanitize(html) 165 } 166 167 + func (rctx *RenderContext) SanitizeDescription(html string) string { 168 + return rctx.Sanitizer.descriptionPolicy.Sanitize(html) 169 + } 170 + 171 type MarkdownTransformer struct { 172 rctx *RenderContext 173 }
+20 -2
appview/pages/markup/sanitizer.go
··· 11 ) 12 13 type Sanitizer struct { 14 - defaultPolicy *bluemonday.Policy 15 } 16 17 func NewSanitizer() Sanitizer { 18 return Sanitizer{ 19 - defaultPolicy: defaultPolicy(), 20 } 21 } 22 ··· 90 91 return policy 92 }
··· 11 ) 12 13 type Sanitizer struct { 14 + defaultPolicy *bluemonday.Policy 15 + descriptionPolicy *bluemonday.Policy 16 } 17 18 func NewSanitizer() Sanitizer { 19 return Sanitizer{ 20 + defaultPolicy: defaultPolicy(), 21 + descriptionPolicy: descriptionPolicy(), 22 } 23 } 24 ··· 92 93 return policy 94 } 95 + 96 + func descriptionPolicy() *bluemonday.Policy { 97 + policy := bluemonday.NewPolicy() 98 + policy.AllowStandardURLs() 99 + 100 + // allow italics and bold. 101 + policy.AllowElements("i", "b", "em", "strong") 102 + 103 + // allow code. 104 + policy.AllowElements("code") 105 + 106 + // allow links 107 + policy.AllowAttrs("href", "target", "rel").OnElements("a") 108 + 109 + return policy 110 + }
+1 -1
appview/pages/templates/repo/issues/issue.html
··· 13 {{ define "repoContent" }} 14 <header class="pb-4"> 15 <h1 class="text-2xl"> 16 - {{ .Issue.Title }} 17 <span class="text-gray-500 dark:text-gray-400"> 18 #{{ .Issue.IssueId }} 19 </span>
··· 13 {{ define "repoContent" }} 14 <header class="pb-4"> 15 <h1 class="text-2xl"> 16 + {{ .Issue.Title | description }} 17 <span class="text-gray-500 dark:text-gray-400"> 18 #{{ .Issue.IssueId }} 19 </span>
+1 -1
appview/pages/templates/repo/issues/issues.html
··· 50 <a 51 href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" 52 class="no-underline hover:underline"> 53 - {{ .Title }} 54 <span class="text-gray-500">#{{ .IssueId }}</span> 55 </a> 56 </div>
··· 50 <a 51 href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}" 52 class="no-underline hover:underline"> 53 + {{ .Title | description }} 54 <span class="text-gray-500">#{{ .IssueId }}</span> 55 </a> 56 </div>
+1 -1
appview/pages/templates/repo/pulls/fragments/summarizedPullHeader.html
··· 9 </div> 10 <span class="truncate text-sm text-gray-800 dark:text-gray-200"> 11 <span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span> 12 - {{ .Title }} 13 </span> 14 </div> 15
··· 9 </div> 10 <span class="truncate text-sm text-gray-800 dark:text-gray-200"> 11 <span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span> 12 + {{ .Title | description }} 13 </span> 14 </div> 15
+1 -1
appview/pages/templates/repo/pulls/pull.html
··· 149 {{ end }} 150 </div> 151 <div class="flex items-center"> 152 - <span>{{ .Title }}</span> 153 {{ if gt (len .Body) 0 }} 154 <button 155 class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
··· 149 {{ end }} 150 </div> 151 <div class="flex items-center"> 152 + <span>{{ .Title | description }}</span> 153 {{ if gt (len .Body) 0 }} 154 <button 155 class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
+1 -1
appview/pages/templates/repo/pulls/pulls.html
··· 60 <a 61 href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}" 62 class="dark:text-white"> 63 - {{ .Title }} 64 <span class="text-gray-500 dark:text-gray-400"> 65 #{{ .PullId }} 66 </span>
··· 60 <a 61 href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}" 62 class="dark:text-white"> 63 + {{ .Title | description }} 64 <span class="text-gray-500 dark:text-gray-400"> 65 #{{ .PullId }} 66 </span>