| // Copyright 2019 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package frontend |
| |
| import ( |
| "context" |
| "fmt" |
| "html/template" |
| "regexp" |
| "strings" |
| |
| "golang.org/x/pkgsite/internal" |
| "golang.org/x/pkgsite/internal/log" |
| "golang.org/x/pkgsite/internal/stdlib" |
| ) |
| |
| // DocumentationDetails contains data for the doc template. |
| type DocumentationDetails struct { |
| GOOS string |
| GOARCH string |
| Documentation template.HTML |
| } |
| |
| // addDocQueryParam controls whether to use a regexp replacement to append |
| // ?tab=doc to urls linking to package identifiers within the documentation. |
| var addDocQueryParam = true |
| |
| // fetchDocumentationDetails returns a DocumentationDetails constructed from pkg. |
| func fetchDocumentationDetails(pkg *internal.LegacyVersionedPackage) *DocumentationDetails { |
| docHTML := pkg.DocumentationHTML |
| if addDocQueryParam { |
| docHTML = hackUpDocumentation(docHTML) |
| } |
| return &DocumentationDetails{ |
| GOOS: pkg.GOOS, |
| GOARCH: pkg.GOARCH, |
| Documentation: template.HTML(docHTML), |
| } |
| } |
| |
| // fetchDocumentationDetails returnsNew a DocumentationDetails constructed from doc. |
| func fetchDocumentationDetailsNew(doc *internal.Documentation) *DocumentationDetails { |
| docHTML := doc.HTML |
| if addDocQueryParam { |
| docHTML = hackUpDocumentation(docHTML) |
| } |
| return &DocumentationDetails{ |
| GOOS: doc.GOOS, |
| GOARCH: doc.GOARCH, |
| Documentation: template.HTML(docHTML), |
| } |
| } |
| |
| // packageLinkRegexp matches cross-package identifier links that have been |
| // generated by the dochtml package. At the time this hack was added, these |
| // links are all constructed to have either the form |
| // <a href="/pkg/[path]">[name]</a> |
| // or the form |
| // <a href="/pkg/[path]#identifier">[name]</a> |
| // |
| // The packageLinkRegexp mutates these links as follows: |
| // - remove the now unnecessary '/pkg' path prefix |
| // - add an explicit ?tab=doc after the path. |
| var packageLinkRegexp = regexp.MustCompile(`(<a href="/)pkg/([^?#"]+)((?:#[^"]*)?">.*?</a>)`) |
| |
| func hackUpDocumentation(docHTML string) string { |
| return packageLinkRegexp.ReplaceAllString(docHTML, `$1$2?tab=doc$3`) |
| } |
| |
| // fileSource returns the original filepath in the module zip where the given |
| // filePath can be found. For std, the corresponding URL in |
| // go.google.source.com/go is returned. |
| func fileSource(modulePath, version, filePath string) string { |
| if modulePath != stdlib.ModulePath { |
| return fmt.Sprintf("%s@%s/%s", modulePath, version, filePath) |
| } |
| |
| root := strings.TrimPrefix(stdlib.GoRepoURL, "https://") |
| tag, err := stdlib.TagForVersion(version) |
| if err != nil { |
| // This should never happen unless there is a bug in |
| // stdlib.TagForVersion. In which case, fallback to the default |
| // zipFilePath. |
| log.Errorf(context.TODO(), "fileSource: %v", err) |
| return fmt.Sprintf("%s/+/refs/heads/master/%s", root, filePath) |
| } |
| return fmt.Sprintf("%s/+/refs/tags/%s/%s", root, tag, filePath) |
| } |