4
4
package markup
5
5
6
6
import (
7
+ "strconv"
7
8
"strings"
8
9
9
- "code.gitea.io/gitea/modules/base"
10
10
"code.gitea.io/gitea/modules/httplib"
11
11
"code.gitea.io/gitea/modules/log"
12
12
"code.gitea.io/gitea/modules/references"
@@ -16,8 +16,16 @@ import (
16
16
"code.gitea.io/gitea/modules/util"
17
17
18
18
"golang.org/x/net/html"
19
+ "golang.org/x/net/html/atom"
19
20
)
20
21
22
+ type RenderIssueIconTitleOptions struct {
23
+ OwnerName string
24
+ RepoName string
25
+ LinkHref string
26
+ IssueIndex int64
27
+ }
28
+
21
29
func fullIssuePatternProcessor (ctx * RenderContext , node * html.Node ) {
22
30
if ctx .RenderOptions .Metas == nil {
23
31
return
@@ -66,6 +74,27 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) {
66
74
}
67
75
}
68
76
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
+
69
98
func issueIndexPatternProcessor (ctx * RenderContext , node * html.Node ) {
70
99
if ctx .RenderOptions .Metas == nil {
71
100
return
@@ -76,50 +105,46 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
76
105
// old logic: crossLinkOnly := ctx.RenderOptions.Metas["mode"] == "document" && !ctx.IsWiki
77
106
crossLinkOnly := ctx .RenderOptions .Metas ["markupAllowShortIssuePattern" ] != "true"
78
107
79
- var (
80
- found bool
81
- ref * references.RenderizableReference
82
- )
108
+ var ref * references.RenderizableReference
83
109
84
110
next := node .NextSibling
85
-
86
111
for node != nil && node != next {
87
112
_ , hasExtTrackFormat := ctx .RenderOptions .Metas ["format" ]
88
113
89
114
// Repos with external issue trackers might still need to reference local PRs
90
115
// We need to concern with the first one that shows up in the text, whichever it is
91
116
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 )
93
118
94
119
switch ctx .RenderOptions .Metas ["style" ] {
95
120
case "" , IssueNameStyleNumeric :
96
- found , ref = foundNumeric , refNumeric
121
+ ref = refNumeric
97
122
case IssueNameStyleAlphanumeric :
98
- found , ref = references .FindRenderizableReferenceAlphanumeric (node .Data )
123
+ ref = references .FindRenderizableReferenceAlphanumeric (node .Data )
99
124
case IssueNameStyleRegexp :
100
125
pattern , err := regexplru .GetCompiled (ctx .RenderOptions .Metas ["regexp" ])
101
126
if err != nil {
102
127
return
103
128
}
104
- found , ref = references .FindRenderizableReferenceRegexp (node .Data , pattern )
129
+ ref = references .FindRenderizableReferenceRegexp (node .Data , pattern )
105
130
}
106
131
107
132
// Repos with external issue trackers might still need to reference local PRs
108
133
// We need to concern with the first one that shows up in the text, whichever it is
109
134
if hasExtTrackFormat && ! isNumericStyle && refNumeric != nil {
110
135
// If numeric (PR) was found, and it was BEFORE the non-numeric pattern, use that
111
136
// 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 {
114
138
ref = refNumeric
115
139
}
116
140
}
117
- if ! found {
141
+
142
+ if ref == nil {
118
143
return
119
144
}
120
145
121
146
var link * html.Node
122
- reftext := node .Data [ref .RefLocation .Start :ref .RefLocation .End ]
147
+ refText := node .Data [ref .RefLocation .Start :ref .RefLocation .End ]
123
148
if hasExtTrackFormat && ! ref .IsPull {
124
149
ctx .RenderOptions .Metas ["index" ] = ref .Issue
125
150
@@ -129,18 +154,23 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
129
154
log .Error ("unable to expand template vars for ref %s, err: %v" , ref .Issue , err )
130
155
}
131
156
132
- link = createLink (ctx , res , reftext , "ref-issue ref-external-issue" )
157
+ link = createLink (ctx , res , refText , "ref-issue ref-external-issue" )
133
158
} else {
134
159
// Path determines the type of link that will be rendered. It's unknown at this point whether
135
160
// the linked item is actually a PR or an issue. Luckily it's of no real consequence because
136
161
// 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 )
137
164
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" )
144
174
}
145
175
}
146
176
@@ -168,21 +198,3 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
168
198
node = node .NextSibling .NextSibling .NextSibling .NextSibling
169
199
}
170
200
}
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