in examples.go [55:122]
func newExamplesHandler(gotip bool, modtime time.Time) (*examplesHandler, error) {
const dir = "examples"
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
var examples []example
for _, entry := range entries {
name := entry.Name()
// Read examples ending in .txt, skipping those ending in .gotip.txt if
// gotip is not set.
prefix := "" // if non-empty, this is a relevant example file
if strings.HasSuffix(name, ".gotip.txt") {
if gotip {
prefix = strings.TrimSuffix(name, ".gotip.txt")
}
} else if strings.HasSuffix(name, ".txt") {
prefix = strings.TrimSuffix(name, ".txt")
}
if prefix == "" {
continue
}
data, err := os.ReadFile(filepath.Join(dir, name))
if err != nil {
return nil, err
}
content := string(data)
// Extract the magic "// Title:" comment specifying the example's title.
nl := strings.IndexByte(content, '\n')
const titlePrefix = "// Title:"
if nl == -1 || !strings.HasPrefix(content, titlePrefix) {
return nil, fmt.Errorf("malformed example for %q: must start with a title line beginning %q", name, titlePrefix)
}
title := strings.TrimPrefix(content[:nl], titlePrefix)
title = strings.TrimSpace(title)
examples = append(examples, example{
Title: title,
Path: name,
Content: content[nl+1:],
})
}
// Sort by title, before prepending the hello example (we always want Hello
// to be first).
sort.Slice(examples, func(i, j int) bool {
return examples[i].Title < examples[j].Title
})
// For Gotip, serve hello content that includes the Go version.
hi := hello
if gotip {
hi = helloGotip
}
examples = append([]example{
{"Hello, playground", "hello.txt", hi},
}, examples...)
return &examplesHandler{
modtime: modtime,
examples: examples,
}, nil
}