9191 IssueNumericPattern = regexp .MustCompile (`( |^|\()#[0-9]+\b` )
9292 // IssueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
9393 IssueAlphanumericPattern = regexp .MustCompile (`( |^|\()[A-Z]{1,10}-[1-9][0-9]*\b` )
94+ // CrossReferenceIssueNumericPattern matches string that references a numeric issue in a difference repository
95+ // e.g. gogits/gogs#12345
96+ CrossReferenceIssueNumericPattern = regexp .MustCompile (`( |^)[0-9a-zA-Z]+/[0-9a-zA-Z]+#[0-9]+\b` )
9497
9598 // Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
9699 // 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) {
156159 if j == - 1 {
157160 j = len (m )
158161 }
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 )
160175 return
161176 }
162177 }
@@ -263,6 +278,23 @@ func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string, metas map[string
263278 return rawBytes
264279}
265280
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+
266298// RenderSha1CurrentPattern renders SHA1 strings to corresponding links that assumes in the same repository.
267299func RenderSha1CurrentPattern (rawBytes []byte , urlPrefix string ) []byte {
268300 return []byte (Sha1CurrentPattern .ReplaceAllStringFunc (string (rawBytes [:]), func (m string ) string {
@@ -283,6 +315,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin
283315 }
284316
285317 rawBytes = RenderIssueIndexPattern (rawBytes , urlPrefix , metas )
318+ rawBytes = RenderCrossReferenceIssueIndexPattern (rawBytes , urlPrefix , metas )
286319 rawBytes = RenderSha1CurrentPattern (rawBytes , urlPrefix )
287320 return rawBytes
288321}
0 commit comments