package main import ( "bytes" "errors" "gopkg.in/yaml.v2" "strings" ) type HugoFrontmatter struct { Title string `yaml:"title,omitempty"` Date string `yaml:"date,omitempty"` Lastmod string `yaml:"lastmod,omitempty"` Tags []string `yaml:"tags,omitempty"` ExternalURL string `yaml:"externalURL,omitempty"` Indieweb HugoFrontmatterIndieweb `yaml:"indieweb,omitempty"` Syndicate []string `yaml:"syndicate,omitempty"` TranslationKey string `yaml:"translationKey,omitempty"` Images []string `yaml:"images,omitempty"` Audio string `yaml:"audio,omitempty"` } type HugoFrontmatterIndieweb struct { Reply HugoFrontmatterReply `yaml:"reply,omitempty"` Like HugoFrontmatterLike `yaml:"like,omitempty"` } type HugoFrontmatterReply struct { Link string `yaml:"link,omitempty"` Title string `yaml:"title,omitempty"` } type HugoFrontmatterLike struct { Link string `yaml:"link,omitempty"` Title string `yaml:"title,omitempty"` } func writeFrontMatter(entry *Entry) (frontmatter string, err error) { var buff bytes.Buffer writeFrontmatter := &HugoFrontmatter{ Title: entry.title, Date: entry.date, Lastmod: entry.lastmod, Tags: entry.tags, ExternalURL: entry.link, Indieweb: HugoFrontmatterIndieweb{ Reply: HugoFrontmatterReply{ Link: entry.replyLink, Title: entry.replyTitle, }, Like: HugoFrontmatterLike{ Link: entry.likeLink, Title: entry.likeTitle, }, }, Syndicate: entry.syndicate, TranslationKey: entry.translationKey, Audio: entry.audio, } for _, image := range entry.images { writeFrontmatter.Images = append(writeFrontmatter.Images, image.url) } yamlBytes, err := yaml.Marshal(&writeFrontmatter) if err != nil { err = errors.New("failed marshaling frontmatter") return } buff.WriteString("---\n") buff.Write(yamlBytes) buff.WriteString("---\n") frontmatter = buff.String() return } func WriteHugoPost(entry *Entry) (string, error) { var buff bytes.Buffer frontmatter, err := writeFrontMatter(entry) if err != nil { return "", err } buff.WriteString(frontmatter) if len(entry.content) > 0 { buff.WriteString(entry.content) } return buff.String(), nil } func readFrontMatter(frontmatter string, entry *Entry) (err error) { parsedFrontmatter := &HugoFrontmatter{} err = yaml.Unmarshal([]byte(frontmatter), &parsedFrontmatter) if err != nil { err = errors.New("failed parsing frontmatter") } if len(parsedFrontmatter.Title) > 0 { entry.title = parsedFrontmatter.Title } if len(parsedFrontmatter.Date) > 0 { entry.date = parsedFrontmatter.Date } if len(parsedFrontmatter.Lastmod) > 0 { entry.lastmod = parsedFrontmatter.Lastmod } if len(parsedFrontmatter.Tags) > 0 { entry.tags = parsedFrontmatter.Tags } if len(parsedFrontmatter.ExternalURL) > 0 { entry.link = parsedFrontmatter.ExternalURL } if len(parsedFrontmatter.Indieweb.Reply.Link) > 0 { entry.replyLink = parsedFrontmatter.Indieweb.Reply.Link } if len(parsedFrontmatter.Indieweb.Reply.Title) > 0 { entry.replyTitle = parsedFrontmatter.Indieweb.Reply.Title } if len(parsedFrontmatter.Indieweb.Like.Link) > 0 { entry.replyLink = parsedFrontmatter.Indieweb.Like.Link } if len(parsedFrontmatter.Indieweb.Like.Title) > 0 { entry.replyTitle = parsedFrontmatter.Indieweb.Like.Title } if len(parsedFrontmatter.Syndicate) > 0 { entry.syndicate = parsedFrontmatter.Syndicate } if len(parsedFrontmatter.TranslationKey) > 0 { entry.translationKey = parsedFrontmatter.TranslationKey } if len(parsedFrontmatter.Images) > 0 { for _, image := range parsedFrontmatter.Images { entry.images = append(entry.images, Image{url: image}) } } if len(parsedFrontmatter.Audio) > 0 { entry.audio = parsedFrontmatter.Audio } return } func ReadHugoPost(fileContent string) (entry *Entry, err error) { parts := strings.Split(fileContent, "---\n") if len(parts) != 3 { err = errors.New("empty frontmatter or content") return } entry = new(Entry) err = readFrontMatter(parts[1], entry) if err != nil { return } entry.content = strings.TrimSuffix(parts[2], "\n") return }