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