91
91
IssueNumericPattern = regexp .MustCompile (`( |^|\()#[0-9]+\b` )
92
92
// IssueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
93
93
IssueAlphanumericPattern = regexp .MustCompile (`( |^|\()[A-Z]{1,10}-[1-9][0-9]*\b` )
94
+ // CrossReferenceIssueNumericPattern matches string that references a numeric issue in a different repository
95
+ // e.g. gogits/gogs#12345
96
+ CrossReferenceIssueNumericPattern = regexp .MustCompile (`( |^)[0-9a-zA-Z]+/[0-9a-zA-Z]+#[0-9]+\b` )
94
97
95
98
// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
96
99
// FIXME: this pattern matches pure numbers as well, right now we do a hack to check in RenderSha1CurrentPattern
@@ -156,7 +159,19 @@ func (r *Renderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {
156
159
if j == - 1 {
157
160
j = len (m )
158
161
}
159
- out .WriteString (fmt .Sprintf (`<a href="%s">#%s</a>` , m , base .ShortSha (string (m [i + 7 :j ]))))
162
+
163
+ issue := string (m [i + 7 : j ])
164
+ fullRepoURL := setting .AppURL + strings .TrimPrefix (r .urlPrefix , "/" )
165
+ var link string
166
+ if strings .HasPrefix (string (m ), fullRepoURL ) {
167
+ // Use a short issue reference if the URL refers to this repository
168
+ link = fmt .Sprintf (`<a href="%s">#%s</a>` , m , issue )
169
+ } else {
170
+ // Use a cross-repository issue reference if the URL refers to a different repository
171
+ repo := string (m [len (setting .AppURL ) : i - 1 ])
172
+ link = fmt .Sprintf (`<a href="%s">%s#%s</a>` , m , repo , issue )
173
+ }
174
+ out .WriteString (link )
160
175
return
161
176
}
162
177
}
@@ -263,6 +278,23 @@ func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string, metas map[string
263
278
return rawBytes
264
279
}
265
280
281
+ // RenderCrossReferenceIssueIndexPattern renders issue indexes from other repositories to corresponding links.
282
+ func RenderCrossReferenceIssueIndexPattern (rawBytes []byte , urlPrefix string , metas map [string ]string ) []byte {
283
+ ms := CrossReferenceIssueNumericPattern .FindAll (rawBytes , - 1 )
284
+ for _ , m := range ms {
285
+ if m [0 ] == ' ' || m [0 ] == '(' {
286
+ m = m [1 :] // ignore leading space or opening parentheses
287
+ }
288
+
289
+ repo := string (bytes .Split (m , []byte ("#" ))[0 ])
290
+ issue := string (bytes .Split (m , []byte ("#" ))[1 ])
291
+
292
+ link := fmt .Sprintf (`<a href="%s%s/issues/%s">%s</a>` , setting .AppURL , repo , issue , m )
293
+ rawBytes = bytes .Replace (rawBytes , m , []byte (link ), 1 )
294
+ }
295
+ return rawBytes
296
+ }
297
+
266
298
// RenderSha1CurrentPattern renders SHA1 strings to corresponding links that assumes in the same repository.
267
299
func RenderSha1CurrentPattern (rawBytes []byte , urlPrefix string ) []byte {
268
300
return []byte (Sha1CurrentPattern .ReplaceAllStringFunc (string (rawBytes [:]), func (m string ) string {
@@ -283,6 +315,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin
283
315
}
284
316
285
317
rawBytes = RenderIssueIndexPattern (rawBytes , urlPrefix , metas )
318
+ rawBytes = RenderCrossReferenceIssueIndexPattern (rawBytes , urlPrefix , metas )
286
319
rawBytes = RenderSha1CurrentPattern (rawBytes , urlPrefix )
287
320
return rawBytes
288
321
}
0 commit comments