diff --git a/reflink.go b/reflink.go index 0963eb0..3ae60e6 100644 --- a/reflink.go +++ b/reflink.go @@ -214,7 +214,46 @@ func (l *Reflinker) linkGitHubRefs(t *ast.Text) { var reGitHubCommitPath = regexp.MustCompile(`^/([^/]+/[^/]+)/commit/([[:xdigit:]]{7,})`) -func (l *Reflinker) linkGitHubURL(n *ast.AutoLink, src []byte) { +func (l *Reflinker) linkCommitURL(m [][]byte, url []byte, start, end int) { + slug, hash := m[1], m[2] + if len(hash) > 10 { + hash = hash[:10] + } + + var replaced string + if bytes.HasPrefix(url, []byte(l.repo)) { + replaced = fmt.Sprintf("[`%s`](%s)", hash, url) + } else { + replaced = fmt.Sprintf("[`%s@%s`](%s)", slug, hash, url) + } + + l.links = append(l.links, refLink{ + start: start, + end: end, + text: replaced, + }) +} + +var reGitHubIssuePath = regexp.MustCompile(`^/([^/]+/[^/]+)/(?:pull|issues)/(\d+)`) + +func (l *Reflinker) linkIssueURL(m [][]byte, url []byte, start, end int) { + slug, num := m[1], m[2] + + var replaced string + if bytes.HasPrefix(url, []byte(l.repo)) { + replaced = fmt.Sprintf("[#%s](%s)", num, url) + } else { + replaced = fmt.Sprintf("[%s#%s](%s)", slug, num, url) + } + + l.links = append(l.links, refLink{ + start: start, + end: end, + text: replaced, + }) +} + +func (l *Reflinker) linkURL(n *ast.AutoLink, src []byte) { start := 0 if p := n.PreviousSibling(); p != nil { t := p.(*ast.Text) @@ -249,28 +288,13 @@ func (l *Reflinker) linkGitHubURL(n *ast.AutoLink, src []byte) { return } - m := reGitHubCommitPath.FindSubmatch(url[len(home):]) - if m == nil { - return - } + path := url[len(home):] - slug, hash := m[1], m[2] - if len(hash) > 10 { - hash = hash[:10] + if m := reGitHubCommitPath.FindSubmatch(path); m != nil { + l.linkCommitURL(m, url, start, end) + } else if m := reGitHubIssuePath.FindSubmatch(path); m != nil { + l.linkIssueURL(m, url, start, end) } - - var replaced string - if bytes.HasPrefix(url, []byte(l.repo)) { - replaced = fmt.Sprintf("[`%s`](%s)", hash, url) - } else { - replaced = fmt.Sprintf("[`%s@%s`](%s)", slug, hash, url) - } - - l.links = append(l.links, refLink{ - start: start, - end: end, - text: replaced, - }) } // BuildLinkedText builds a markdown text linking all references. @@ -311,7 +335,7 @@ func LinkRefs(input string, repoURL string) string { case *ast.CodeSpan, *ast.Link: return ast.WalkSkipChildren, nil case *ast.AutoLink: - l.linkGitHubURL(n, src) + l.linkURL(n, src) return ast.WalkSkipChildren, nil case *ast.Text: l.linkGitHubRefs(n) diff --git a/reflink_test.go b/reflink_test.go index 374c765..f41ed72 100644 --- a/reflink_test.go +++ b/reflink_test.go @@ -476,6 +476,26 @@ func TestLinkRefs(t *testing.T) { want: "https://github.com/foo/bar/commit/1d457ba853aa10f9a6c925a1b73d5aed38066ffe", repoURL: "https://github.company.com/u/r", }, + { + what: "issue URL inside the repo", + input: "the issue is https://github.com/u/r/issues/123!", + want: "the issue is [#123](https://github.com/u/r/issues/123)!", + }, + { + what: "PR URL inside the repo", + input: "the PR is https://github.com/u/r/pull/123!", + want: "the PR is [#123](https://github.com/u/r/pull/123)!", + }, + { + what: "issue URL outside the repo", + input: "the issue is https://github.com/foo/bar/issues/123!", + want: "the issue is [foo/bar#123](https://github.com/foo/bar/issues/123)!", + }, + { + what: "PR URL outside the repo", + input: "the PR is https://github.com/foo/bar/pull/123!", + want: "the PR is [foo/bar#123](https://github.com/foo/bar/pull/123)!", + }, } for _, tc := range tests {