@@ -0,0 +1,185 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/adrg/frontmatter"
+ "github.com/go-git/go-git/v5"
+ flag "github.com/spf13/pflag"
+ "gopkg.in/yaml.v3"
+)
+
+var (
+ flagHelp *bool = flag.BoolP("help", "h", false, "Show the help message")
+ flagInput *string = flag.StringP("input", "i", "", "Path to input Markdown")
+ flagOutput *string = flag.StringP("output", "o", "", "Path to output PNG")
+ flagFont *string = flag.StringP("font", "f", "", "Name of font used in the cover image")
+ flagMetaSize *int = flag.IntP("metasize", "m", 12, "Size of font for meta information")
+ flagPostTitleSize *int = flag.IntP("posttitlesize", "p", 14, "Size of font for post title")
+ flagSiteTitleSize *int = flag.IntP("sitetitlesize", "s", 10, "Size of font for site title")
+)
+
+func main() {
+ flag.Parse()
+
+ if *flagHelp {
+ help()
+ os.Exit(0)
+ }
+
+ validateFlags()
+
+ postTitle, postSubtitle, postDate, postContent := getPostInfo(*flagInput)
+ postReadTime := getReadTime(postContent)
+ siteTitle := getSiteTitle()
+ dateEdited := getGitDate(*flagInput)
+
+ // TODO: Render information to image
+ fmt.Println(postTitle, postSubtitle, postDate, postReadTime, siteTitle, dateEdited)
+}
+
+// Print help message
+func help() {
+ fmt.Println("\nUsage: p2c [options]")
+ fmt.Println("\nOptions:")
+ flag.PrintDefaults()
+ fmt.Print(`
+example: p2c -i input.md -o output.png -f "Liberation Sans"
+
+p2c is meant for use with Hugo.
+
+It looks at...
+- The Markdown file's frontmatter fields for
+ - title
+ - subtitle
+ - date
+- The site's config.{toml/yaml/yml} fields for
+ - title (site title)
+- The git history to determine the date the post was last edited.
+
+`)
+}
+
+// Validate flags
+func validateFlags() {
+ if *flagInput == "" {
+ fmt.Println("Error: No input file specified")
+ os.Exit(1)
+ }
+ if *flagOutput == "" {
+ fmt.Println("Error: No output file specified")
+ os.Exit(1)
+ }
+ if *flagFont == "" {
+ fmt.Println("Error: No font specified")
+ os.Exit(1)
+ }
+}
+
+// Get the post's title, subtitle, and date
+func getPostInfo(input string) (string, string, string, string) {
+ if _, err := os.Stat(input); os.IsNotExist(err) {
+ fmt.Println("Error: Input file does not exist")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ fileContents, err := os.ReadFile(input)
+ if err != nil {
+ fmt.Println("Error: Could not read input file")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ var fm struct {
+ Title string `yaml:"title"`
+ Subtitle string `yaml:"subtitle"`
+ Date string `yaml:"date"`
+ }
+
+ content, err := frontmatter.Parse(strings.NewReader(string(fileContents)), &fm)
+ if err != nil {
+ fmt.Println("Error: Could not parse frontmatter")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ return fm.Title, fm.Subtitle, fm.Date, string(content)
+}
+
+// Get the read time of the post
+func getReadTime(content string) int {
+ wordCount := len(strings.Fields(content))
+ return wordCount / 200
+}
+
+// Get the site's title
+func getSiteTitle() string {
+ validConf := ""
+ confs := []string{"config.toml", "config.yaml", "config.yml"}
+ for _, conf := range confs {
+ if _, err := os.Stat(conf); os.IsNotExist(err) {
+ continue
+ }
+ validConf = conf
+ }
+ if validConf == "" {
+ fmt.Println("Error: No valid config file found")
+ os.Exit(1)
+ }
+
+ var t struct {
+ Title string `yaml:"title"`
+ }
+
+ f, err := os.Open(validConf)
+ if err != nil {
+ fmt.Println("Error: Could not open config file")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ defer f.Close()
+
+ decoder := yaml.NewDecoder(f)
+ err = decoder.Decode(&t)
+ if err != nil {
+ fmt.Println("Error: Could not parse config file")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ return t.Title
+}
+
+// Get the date the post was last edited
+func getGitDate(input string) string {
+ if _, err := os.Stat(input); os.IsNotExist(err) {
+ fmt.Println("Error: Input file does not exist")
+ os.Exit(1)
+ }
+
+ repo, err := git.PlainOpenWithOptions(".", &git.PlainOpenOptions{DetectDotGit: true})
+ if err != nil {
+ fmt.Println("Error: Could not open git repository")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ commitIter, err := repo.Log(&git.LogOptions{FileName: &input})
+ if err != nil {
+ fmt.Println("Error: Could not get git history")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ commit, err := commitIter.Next()
+ if err != nil {
+ fmt.Println("Error: Could not get git history")
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ return commit.Committer.When.Format("2006-01-02")
+}