···31 Files []*RepoTree_TreeEntry `json:"files" cborgen:"files"`
32 // parent: The parent path in the tree
33 Parent *string `json:"parent,omitempty" cborgen:"parent,omitempty"`
0034 // ref: The git reference used
35 Ref string `json:"ref" cborgen:"ref"`
0000000036}
3738// RepoTree_TreeEntry is a "treeEntry" in the sh.tangled.repo.tree schema.
···31 Files []*RepoTree_TreeEntry `json:"files" cborgen:"files"`
32 // parent: The parent path in the tree
33 Parent *string `json:"parent,omitempty" cborgen:"parent,omitempty"`
34+ // readme: Readme for this file tree
35+ Readme *RepoTree_Readme `json:"readme,omitempty" cborgen:"readme,omitempty"`
36 // ref: The git reference used
37 Ref string `json:"ref" cborgen:"ref"`
38+}
39+40+// RepoTree_Readme is a "readme" in the sh.tangled.repo.tree schema.
41+type RepoTree_Readme struct {
42+ // contents: Contents of the readme file
43+ Contents string `json:"contents" cborgen:"contents"`
44+ // filename: Name of the readme file
45+ Filename string `json:"filename" cborgen:"filename"`
46}
4748// RepoTree_TreeEntry is a "treeEntry" in the sh.tangled.repo.tree schema.
+15-17
appview/pages/markup/format.go
···1package markup
23-import "strings"
0045type Format string
6···10)
1112var FileTypes map[Format][]string = map[Format][]string{
13- FormatMarkdown: []string{".md", ".markdown", ".mdown", ".mkdn", ".mkd"},
14}
1516-// ReadmeFilenames contains the list of common README filenames to search for,
17-// in order of preference. Only includes well-supported formats.
18-var ReadmeFilenames = []string{
19- "README.md", "readme.md",
20- "README",
21- "readme",
22- "README.markdown",
23- "readme.markdown",
24- "README.txt",
25- "readme.txt",
26}
2728func GetFormat(filename string) Format {
29- for format, extensions := range FileTypes {
30- for _, extension := range extensions {
31- if strings.HasSuffix(filename, extension) {
32- return format
33- }
34 }
35 }
36 // default format
···1package markup
23+import (
4+ "regexp"
5+)
67type Format string
8···12)
1314var FileTypes map[Format][]string = map[Format][]string{
15+ FormatMarkdown: {".md", ".markdown", ".mdown", ".mkdn", ".mkd"},
16}
1718+var FileTypePatterns = map[Format]*regexp.Regexp{
19+ FormatMarkdown: regexp.MustCompile(`(?i)\.(md|markdown|mdown|mkdn|mkd)$`),
20+}
21+22+var ReadmePattern = regexp.MustCompile(`(?i)^readme(\.(md|markdown|txt))?$`)
23+24+func IsReadmeFile(filename string) bool {
25+ return ReadmePattern.MatchString(filename)
0026}
2728func GetFormat(filename string) Format {
29+ for format, pattern := range FileTypePatterns {
30+ if pattern.MatchString(filename) {
31+ return format
0032 }
33 }
34 // default format
···484 if xrpcResp.Dotdot != nil {
485 result.DotDot = *xrpcResp.Dotdot
486 }
0000487488 // redirects tree paths trying to access a blob; in this case the result.Files is unpopulated,
489 // so we can safely redirect to the "parent" (which is the same file).
···484 if xrpcResp.Dotdot != nil {
485 result.DotDot = *xrpcResp.Dotdot
486 }
487+ if xrpcResp.Readme != nil {
488+ result.ReadmeFileName = xrpcResp.Readme.Filename
489+ result.Readme = xrpcResp.Readme.Contents
490+ }
491492 // redirects tree paths trying to access a blob; in this case the result.Files is unpopulated,
493 // so we can safely redirect to the "parent" (which is the same file).