package step import "strings" const frontMatterRule = "---" // Meta represents optional metadata that can occur at the very start of // a document. type Meta = map[string] string // SplitMeta parses the metadata (if it exists), returning a map representing it // along with the rest of the input as a string. If there is no metadata, an // empty map will be returned. func SplitMeta (input string) (Meta, string, error) { // i hate crlf!!!!! uwehhh!!! input = strings.ReplaceAll(input, "\r\n", "\n") // stop if there is no front matter if !strings.HasPrefix(input, frontMatterRule + "\n") { return Meta { }, input, nil } // get the start and the end of the front matter input = strings.TrimPrefix(input, frontMatterRule) index := strings.Index(input, "\n" + frontMatterRule + "\n") if index < 0 { return nil, "", ErrFrontMatterNeverClosed } frontMatterRaw := input[:index] body := input[index + len(frontMatterRule) + 2:] frontMatter := make(Meta) // iterate over the lines for _, line := range strings.Split(frontMatterRaw, "\n") { line = strings.TrimSpace(line) if line == "" { continue } key, value, ok := strings.Cut(line, ":") if !ok { return nil, "", ErrFrontMatterMalformed } key = strings.ToLower(strings.TrimSpace(key)) value = strings.TrimSpace(value) if key == "" { return nil, "", ErrFrontMatterMalformed } if _, exists := frontMatter[key]; exists { return nil, "", ErrFrontMatterDuplicateKey } frontMatter[key] = value } return frontMatter, body, nil }