44package markup
55
66import (
7+ "strconv"
78 "strings"
89
9- "code.gitea.io/gitea/modules/base"
1010 "code.gitea.io/gitea/modules/httplib"
1111 "code.gitea.io/gitea/modules/log"
1212 "code.gitea.io/gitea/modules/references"
@@ -16,8 +16,16 @@ import (
1616 "code.gitea.io/gitea/modules/util"
1717
1818 "golang.org/x/net/html"
19+ "golang.org/x/net/html/atom"
1920)
2021
22+ type RenderIssueIconTitleOptions struct {
23+ OwnerName string
24+ RepoName string
25+ LinkHref string
26+ IssueIndex int64
27+ }
28+
2129func fullIssuePatternProcessor (ctx * RenderContext , node * html.Node ) {
2230 if ctx .RenderOptions .Metas == nil {
2331 return
@@ -66,6 +74,27 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) {
6674 }
6775}
6876
77+ func createIssueLinkContentWithSummary (ctx * RenderContext , linkHref string , ref * references.RenderizableReference ) * html.Node {
78+ if DefaultRenderHelperFuncs .RenderRepoIssueIconTitle == nil {
79+ return nil
80+ }
81+ issueIndex , _ := strconv .ParseInt (ref .Issue , 10 , 64 )
82+ h , err := DefaultRenderHelperFuncs .RenderRepoIssueIconTitle (ctx , RenderIssueIconTitleOptions {
83+ OwnerName : ref .Owner ,
84+ RepoName : ref .Name ,
85+ LinkHref : linkHref ,
86+ IssueIndex : issueIndex ,
87+ })
88+ if err != nil {
89+ log .Error ("RenderRepoIssueIconTitle failed: %v" , err )
90+ return nil
91+ }
92+ if h == "" {
93+ return nil
94+ }
95+ return & html.Node {Type : html .RawNode , Data : string (ctx .RenderInternal .ProtectSafeAttrs (h ))}
96+ }
97+
6998func issueIndexPatternProcessor (ctx * RenderContext , node * html.Node ) {
7099 if ctx .RenderOptions .Metas == nil {
71100 return
@@ -76,50 +105,46 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
76105 // old logic: crossLinkOnly := ctx.RenderOptions.Metas["mode"] == "document" && !ctx.IsWiki
77106 crossLinkOnly := ctx .RenderOptions .Metas ["markupAllowShortIssuePattern" ] != "true"
78107
79- var (
80- found bool
81- ref * references.RenderizableReference
82- )
108+ var ref * references.RenderizableReference
83109
84110 next := node .NextSibling
85-
86111 for node != nil && node != next {
87112 _ , hasExtTrackFormat := ctx .RenderOptions .Metas ["format" ]
88113
89114 // Repos with external issue trackers might still need to reference local PRs
90115 // We need to concern with the first one that shows up in the text, whichever it is
91116 isNumericStyle := ctx .RenderOptions .Metas ["style" ] == "" || ctx .RenderOptions .Metas ["style" ] == IssueNameStyleNumeric
92- foundNumeric , refNumeric := references .FindRenderizableReferenceNumeric (node .Data , hasExtTrackFormat && ! isNumericStyle , crossLinkOnly )
117+ refNumeric := references .FindRenderizableReferenceNumeric (node .Data , hasExtTrackFormat && ! isNumericStyle , crossLinkOnly )
93118
94119 switch ctx .RenderOptions .Metas ["style" ] {
95120 case "" , IssueNameStyleNumeric :
96- found , ref = foundNumeric , refNumeric
121+ ref = refNumeric
97122 case IssueNameStyleAlphanumeric :
98- found , ref = references .FindRenderizableReferenceAlphanumeric (node .Data )
123+ ref = references .FindRenderizableReferenceAlphanumeric (node .Data )
99124 case IssueNameStyleRegexp :
100125 pattern , err := regexplru .GetCompiled (ctx .RenderOptions .Metas ["regexp" ])
101126 if err != nil {
102127 return
103128 }
104- found , ref = references .FindRenderizableReferenceRegexp (node .Data , pattern )
129+ ref = references .FindRenderizableReferenceRegexp (node .Data , pattern )
105130 }
106131
107132 // Repos with external issue trackers might still need to reference local PRs
108133 // We need to concern with the first one that shows up in the text, whichever it is
109134 if hasExtTrackFormat && ! isNumericStyle && refNumeric != nil {
110135 // If numeric (PR) was found, and it was BEFORE the non-numeric pattern, use that
111136 // Allow a free-pass when non-numeric pattern wasn't found.
112- if found && (ref == nil || refNumeric .RefLocation .Start < ref .RefLocation .Start ) {
113- found = foundNumeric
137+ if ref == nil || refNumeric .RefLocation .Start < ref .RefLocation .Start {
114138 ref = refNumeric
115139 }
116140 }
117- if ! found {
141+
142+ if ref == nil {
118143 return
119144 }
120145
121146 var link * html.Node
122- reftext := node .Data [ref .RefLocation .Start :ref .RefLocation .End ]
147+ refText := node .Data [ref .RefLocation .Start :ref .RefLocation .End ]
123148 if hasExtTrackFormat && ! ref .IsPull {
124149 ctx .RenderOptions .Metas ["index" ] = ref .Issue
125150
@@ -129,18 +154,23 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
129154 log .Error ("unable to expand template vars for ref %s, err: %v" , ref .Issue , err )
130155 }
131156
132- link = createLink (ctx , res , reftext , "ref-issue ref-external-issue" )
157+ link = createLink (ctx , res , refText , "ref-issue ref-external-issue" )
133158 } else {
134159 // Path determines the type of link that will be rendered. It's unknown at this point whether
135160 // the linked item is actually a PR or an issue. Luckily it's of no real consequence because
136161 // Gitea will redirect on click as appropriate.
162+ issueOwner := util .Iif (ref .Owner == "" , ctx .RenderOptions .Metas ["user" ], ref .Owner )
163+ issueRepo := util .Iif (ref .Owner == "" , ctx .RenderOptions .Metas ["repo" ], ref .Name )
137164 issuePath := util .Iif (ref .IsPull , "pulls" , "issues" )
138- if ref .Owner == "" {
139- linkHref := ctx .RenderHelper .ResolveLink (util .URLJoin (ctx .RenderOptions .Metas ["user" ], ctx .RenderOptions .Metas ["repo" ], issuePath , ref .Issue ), LinkTypeApp )
140- link = createLink (ctx , linkHref , reftext , "ref-issue" )
141- } else {
142- linkHref := ctx .RenderHelper .ResolveLink (util .URLJoin (ref .Owner , ref .Name , issuePath , ref .Issue ), LinkTypeApp )
143- link = createLink (ctx , linkHref , reftext , "ref-issue" )
165+ linkHref := ctx .RenderHelper .ResolveLink (util .URLJoin (issueOwner , issueRepo , issuePath , ref .Issue ), LinkTypeApp )
166+
167+ // at the moment, only render the issue index in a full line (or simple line) as icon+title
168+ // otherwise it would be too noisy for "take #1 as an example" in a sentence
169+ if node .Parent .DataAtom == atom .Li && ref .RefLocation .Start < 20 && ref .RefLocation .End == len (node .Data ) {
170+ link = createIssueLinkContentWithSummary (ctx , linkHref , ref )
171+ }
172+ if link == nil {
173+ link = createLink (ctx , linkHref , refText , "ref-issue" )
144174 }
145175 }
146176
@@ -168,21 +198,3 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
168198 node = node .NextSibling .NextSibling .NextSibling .NextSibling
169199 }
170200}
171-
172- func commitCrossReferencePatternProcessor (ctx * RenderContext , node * html.Node ) {
173- next := node .NextSibling
174-
175- for node != nil && node != next {
176- found , ref := references .FindRenderizableCommitCrossReference (node .Data )
177- if ! found {
178- return
179- }
180-
181- reftext := ref .Owner + "/" + ref .Name + "@" + base .ShortSha (ref .CommitSha )
182- linkHref := ctx .RenderHelper .ResolveLink (util .URLJoin (ref .Owner , ref .Name , "commit" , ref .CommitSha ), LinkTypeApp )
183- link := createLink (ctx , linkHref , reftext , "commit" )
184-
185- replaceContent (node , ref .RefLocation .Start , ref .RefLocation .End , link )
186- node = node .NextSibling .NextSibling
187- }
188- }
0 commit comments