Fix resolving of URLs in markdown (#401)
Path-only URLs need an absolute reference to be resolved against for printing in markdown Previously we resolved against the URL to the resource we were operating on (eg comment or issue URL). The markdown renderer in the web UI resolves all such URLs relative to the repo base URL. This PR adopts this behaviour in tea, by trimming the URL to a repo base URL via regex. This makes a custom patch to our markdown renderer `glamour` obsolete, which turned out to be an incorrect patch, meaning we can make use of upstream glamour again. Co-authored-by: Norwin <git@nroo.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/401 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: Norwin <noerw@noreply.gitea.io> Co-committed-by: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
parent
dc16643e0d
commit
d2295828d0
2
go.mod
2
go.mod
|
@ -37,5 +37,3 @@ require (
|
||||||
golang.org/x/tools v0.1.5 // indirect
|
golang.org/x/tools v0.1.5 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/charmbracelet/glamour => github.com/noerw/glamour v0.3.0-patch
|
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -39,6 +39,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
|
||||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
|
github.com/charmbracelet/glamour v0.3.0 h1:3H+ZrKlSg8s+WU6V7eF2eRVYt8lCueffbi7r2+ffGkc=
|
||||||
|
github.com/charmbracelet/glamour v0.3.0/go.mod h1:TzF0koPZhqq0YVBNL100cPHznAAjVj7fksX2RInwjGw=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
@ -129,8 +131,6 @@ github.com/muesli/termenv v0.8.1/go.mod h1:kzt/D/4a88RoheZmwfqorY3A+tnsSMA9HJC/f
|
||||||
github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8=
|
github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8=
|
||||||
github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw=
|
github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/noerw/glamour v0.3.0-patch h1:yc3wdbUIySok6KYeX5BtWnlj+PvP1uYeCeTSwq2rtSw=
|
|
||||||
github.com/noerw/glamour v0.3.0-patch/go.mod h1:TzF0koPZhqq0YVBNL100cPHznAAjVj7fksX2RInwjGw=
|
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
func Comments(comments []*gitea.Comment) {
|
func Comments(comments []*gitea.Comment) {
|
||||||
var baseURL string
|
var baseURL string
|
||||||
if len(comments) != 0 {
|
if len(comments) != 0 {
|
||||||
baseURL = comments[0].HTMLURL
|
baseURL = getRepoURL(comments[0].HTMLURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
var out = make([]string, len(comments))
|
var out = make([]string, len(comments))
|
||||||
|
@ -32,7 +32,7 @@ func Comments(comments []*gitea.Comment) {
|
||||||
|
|
||||||
// Comment renders a comment to stdout
|
// Comment renders a comment to stdout
|
||||||
func Comment(c *gitea.Comment) {
|
func Comment(c *gitea.Comment) {
|
||||||
outputMarkdown(formatComment(c), c.HTMLURL)
|
outputMarkdown(formatComment(c), getRepoURL(c.HTMLURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatComment(c *gitea.Comment) string {
|
func formatComment(c *gitea.Comment) string {
|
||||||
|
|
|
@ -6,12 +6,20 @@ package print
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/muesli/termenv"
|
"github.com/muesli/termenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// captures the repo URL part <host>/<owner>/<repo> of an url
|
||||||
|
var repoURLRegex = regexp.MustCompile("^([[:alnum:]]+://[^/]+(?:/[[:alnum:]]+){2})/.*")
|
||||||
|
|
||||||
|
func getRepoURL(resourceURL string) string {
|
||||||
|
return repoURLRegex.ReplaceAllString(resourceURL, "$1/")
|
||||||
|
}
|
||||||
|
|
||||||
// formatSize get kb in int and return string
|
// formatSize get kb in int and return string
|
||||||
func formatSize(kb int64) string {
|
func formatSize(kb int64) string {
|
||||||
if kb < 1024 {
|
if kb < 1024 {
|
||||||
|
|
|
@ -28,7 +28,7 @@ func IssueDetails(issue *gitea.Issue, reactions []*gitea.Reaction) {
|
||||||
out += fmt.Sprintf("\n---\n\n%s\n", formatReactions(reactions))
|
out += fmt.Sprintf("\n---\n\n%s\n", formatReactions(reactions))
|
||||||
}
|
}
|
||||||
|
|
||||||
outputMarkdown(out, issue.HTMLURL)
|
outputMarkdown(out, getRepoURL(issue.HTMLURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatReactions(reactions []*gitea.Reaction) string {
|
func formatReactions(reactions []*gitea.Reaction) string {
|
||||||
|
|
|
@ -64,7 +64,7 @@ func PullDetails(pr *gitea.PullRequest, reviews []*gitea.PullReview, ciStatus *g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outputMarkdown(out, pr.HTMLURL)
|
outputMarkdown(out, getRepoURL(pr.HTMLURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatPRHead(pr *gitea.PullRequest) string {
|
func formatPRHead(pr *gitea.PullRequest) string {
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
<a href="https://pkg.go.dev/github.com/charmbracelet/glamour?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a>
|
<a href="https://pkg.go.dev/github.com/charmbracelet/glamour?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a>
|
||||||
<a href="https://github.com/charmbracelet/glamour/actions"><img src="https://github.com/charmbracelet/glamour/workflows/build/badge.svg" alt="Build Status"></a>
|
<a href="https://github.com/charmbracelet/glamour/actions"><img src="https://github.com/charmbracelet/glamour/workflows/build/badge.svg" alt="Build Status"></a>
|
||||||
<a href="https://coveralls.io/github/charmbracelet/glamour?branch=master"><img src="https://coveralls.io/repos/github/charmbracelet/glamour/badge.svg?branch=master" alt="Coverage Status"></a>
|
<a href="https://coveralls.io/github/charmbracelet/glamour?branch=master"><img src="https://coveralls.io/repos/github/charmbracelet/glamour/badge.svg?branch=master" alt="Coverage Status"></a>
|
||||||
<a href="https://goreportcard.com/report/charmbracelet/glamour"><img src="https://goreportcard.com/badge/charmbracelet/glamour" alt="Go ReportCard"></a>
|
<a href="http://goreportcard.com/report/charmbracelet/glamour"><img src="http://goreportcard.com/badge/charmbracelet/glamour" alt="Go ReportCard"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Stylesheet-based markdown rendering for your CLI apps.
|
Write handsome command-line tools with *Glamour*.
|
||||||
|
|
||||||
![Glamour dark style example](https://stuff.charm.sh/glamour/glamour-example.png)
|
![Glamour dark style example](https://stuff.charm.sh/glamour/glamour-example.png)
|
||||||
|
|
||||||
|
|
|
@ -129,9 +129,6 @@ func (tr *ANSIRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||||
}
|
}
|
||||||
if node.Parent().(*ast.List).IsOrdered() {
|
if node.Parent().(*ast.List).IsOrdered() {
|
||||||
e = l
|
e = l
|
||||||
if node.Parent().(*ast.List).Start != 1 {
|
|
||||||
e += uint(node.Parent().(*ast.List).Start) - 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post := "\n"
|
post := "\n"
|
||||||
|
@ -156,7 +153,6 @@ func (tr *ANSIRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||||
return Element{
|
return Element{
|
||||||
Exiting: post,
|
Exiting: post,
|
||||||
Renderer: &ItemElement{
|
Renderer: &ItemElement{
|
||||||
IsOrdered: node.Parent().(*ast.List).IsOrdered(),
|
|
||||||
Enumeration: e,
|
Enumeration: e,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func (e *ImageElement) Render(w io.Writer, ctx RenderContext) error {
|
||||||
}
|
}
|
||||||
if len(e.URL) > 0 {
|
if len(e.URL) > 0 {
|
||||||
el := &BaseElement{
|
el := &BaseElement{
|
||||||
Token: resolveURL(e.BaseURL, e.URL),
|
Token: resolveRelativeURL(e.BaseURL, e.URL),
|
||||||
Prefix: " ",
|
Prefix: " ",
|
||||||
Style: ctx.options.Styles.Image,
|
Style: ctx.options.Styles.Image,
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (e *LinkElement) Render(w io.Writer, ctx RenderContext) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
el := &BaseElement{
|
el := &BaseElement{
|
||||||
Token: resolveURL(e.BaseURL, e.URL),
|
Token: resolveRelativeURL(e.BaseURL, e.URL),
|
||||||
Prefix: pre,
|
Prefix: pre,
|
||||||
Style: style,
|
Style: style,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,12 @@ import (
|
||||||
|
|
||||||
// An ItemElement is used to render items inside a list.
|
// An ItemElement is used to render items inside a list.
|
||||||
type ItemElement struct {
|
type ItemElement struct {
|
||||||
IsOrdered bool
|
|
||||||
Enumeration uint
|
Enumeration uint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemElement) Render(w io.Writer, ctx RenderContext) error {
|
func (e *ItemElement) Render(w io.Writer, ctx RenderContext) error {
|
||||||
var el *BaseElement
|
var el *BaseElement
|
||||||
if e.IsOrdered {
|
if e.Enumeration > 0 {
|
||||||
el = &BaseElement{
|
el = &BaseElement{
|
||||||
Style: ctx.options.Styles.Enumeration,
|
Style: ctx.options.Styles.Enumeration,
|
||||||
Prefix: strconv.FormatInt(int64(e.Enumeration), 10),
|
Prefix: strconv.FormatInt(int64(e.Enumeration), 10),
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||||
mw := NewMarginWriter(ctx, w, rules)
|
mw := NewMarginWriter(ctx, w, rules)
|
||||||
if len(strings.TrimSpace(bs.Current().Block.String())) > 0 {
|
if len(strings.TrimSpace(bs.Current().Block.String())) > 0 {
|
||||||
flow := wordwrap.NewWriter(int(bs.Width(ctx)))
|
flow := wordwrap.NewWriter(int(bs.Width(ctx)))
|
||||||
flow.KeepNewlines = ctx.options.PreserveNewLines
|
flow.KeepNewlines = false
|
||||||
_, _ = flow.Write(bs.Current().Block.Bytes())
|
_, _ = flow.Write(bs.Current().Block.Bytes())
|
||||||
flow.Close()
|
flow.Close()
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ansi
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/muesli/termenv"
|
"github.com/muesli/termenv"
|
||||||
east "github.com/yuin/goldmark-emoji/ast"
|
east "github.com/yuin/goldmark-emoji/ast"
|
||||||
|
@ -16,7 +17,6 @@ import (
|
||||||
type Options struct {
|
type Options struct {
|
||||||
BaseURL string
|
BaseURL string
|
||||||
WordWrap int
|
WordWrap int
|
||||||
PreserveNewLines bool
|
|
||||||
ColorProfile termenv.Profile
|
ColorProfile termenv.Profile
|
||||||
Styles StyleConfig
|
Styles StyleConfig
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ func isChild(node ast.Node) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveURL(baseURL string, rel string) string {
|
func resolveRelativeURL(baseURL string, rel string) string {
|
||||||
u, err := url.Parse(rel)
|
u, err := url.Parse(rel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rel
|
return rel
|
||||||
|
@ -157,6 +157,7 @@ func resolveURL(baseURL string, rel string) string {
|
||||||
if u.IsAbs() {
|
if u.IsAbs() {
|
||||||
return rel
|
return rel
|
||||||
}
|
}
|
||||||
|
u.Path = strings.TrimPrefix(u.Path, "/")
|
||||||
|
|
||||||
base, err := url.Parse(baseURL)
|
base, err := url.Parse(baseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -185,14 +185,6 @@ func WithWordWrap(wordWrap int) TermRendererOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithWordWrap sets a TermRenderer's word wrap.
|
|
||||||
func WithPreservedNewLines() TermRendererOption {
|
|
||||||
return func(tr *TermRenderer) error {
|
|
||||||
tr.ansiOptions.PreserveNewLines = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEmoji sets a TermRenderer's emoji rendering.
|
// WithEmoji sets a TermRenderer's emoji rendering.
|
||||||
func WithEmoji() TermRendererOption {
|
func WithEmoji() TermRendererOption {
|
||||||
return func(tr *TermRenderer) error {
|
return func(tr *TermRenderer) error {
|
||||||
|
|
|
@ -74,7 +74,7 @@ github.com/araddon/dateparse
|
||||||
# github.com/aymerick/douceur v0.2.0
|
# github.com/aymerick/douceur v0.2.0
|
||||||
github.com/aymerick/douceur/css
|
github.com/aymerick/douceur/css
|
||||||
github.com/aymerick/douceur/parser
|
github.com/aymerick/douceur/parser
|
||||||
# github.com/charmbracelet/glamour v0.3.0 => github.com/noerw/glamour v0.3.0-patch
|
# github.com/charmbracelet/glamour v0.3.0
|
||||||
github.com/charmbracelet/glamour
|
github.com/charmbracelet/glamour
|
||||||
github.com/charmbracelet/glamour/ansi
|
github.com/charmbracelet/glamour/ansi
|
||||||
# github.com/cpuguy83/go-md2man/v2 v2.0.1
|
# github.com/cpuguy83/go-md2man/v2 v2.0.1
|
||||||
|
|
Loading…
Reference in New Issue