package main import ( "errors" "fmt" "os" "path/filepath" "slices" "strings" "time" ) type PostWithDate struct { Post string Date time.Time } func getAllPosts(dir string) ([]string, error) { entries, err := os.ReadDir(dir) if err != nil { return []string{}, err } posts := make([]PostWithDate, 0) for _, entry := range entries { if filepath.Ext(entry.Name()) != ".md" { continue } content, err := os.ReadFile(filepath.Join(dir, entry.Name())) if err != nil { return []string{}, err } postInfo, err := getPostInfo(string(content)) if err != nil { return []string{}, err } posts = append(posts, PostWithDate{ Post: string(content), Date: postInfo.Date, }) } slices.SortFunc(posts, func(a PostWithDate, b PostWithDate) int { if a.Date.Before(b.Date) { return 1 } else { return -1 } }) justPosts := make([]string, len(posts)) for i, v := range posts { justPosts[i] = v.Post } return justPosts, nil } type postInfo struct { Title string Date time.Time } // TODO: this could actually be a parser // Pull out the old course notes on recursive descent. func getPostInfo(post string) (postInfo, error) { lines := strings.Split(post, "\n") if len(lines) == 0 { return postInfo{}, errors.New("Post has 0 lines") } if lines[0] != "+++" { return postInfo{}, errors.New("Post does not contain metadata field +++ on first line") } info := postInfo{} for _, line := range lines { splitLine := strings.Split(line, " = ") if len(splitLine) != 2 { continue } switch splitLine[0] { case "title": info.Title = splitLine[1] case "date": fmt.Println(splitLine[1]) t, err := time.Parse(time.DateOnly, splitLine[1][1:len(splitLine[1])-1]) if err != nil { continue } info.Date = t } } return info, nil }