github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/markup/markdown/meta.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package markdown 7 8 import ( 9 "errors" 10 "strings" 11 12 "gopkg.in/yaml.v2" 13 ) 14 15 func isYAMLSeparator(line string) bool { 16 line = strings.TrimSpace(line) 17 for i := 0; i < len(line); i++ { 18 if line[i] != '-' { 19 return false 20 } 21 } 22 return len(line) > 2 23 } 24 25 // ExtractMetadata consumes a markdown file, parses YAML frontmatter, 26 // and returns the frontmatter metadata separated from the markdown content 27 func ExtractMetadata(contents string, out interface{}) (string, error) { 28 var front, body []string 29 lines := strings.Split(contents, "\n") 30 for idx, line := range lines { 31 if idx == 0 { 32 // First line has to be a separator 33 if !isYAMLSeparator(line) { 34 return "", errors.New("frontmatter must start with a separator line") 35 } 36 continue 37 } 38 if isYAMLSeparator(line) { 39 front, body = lines[1:idx], lines[idx+1:] 40 break 41 } 42 } 43 44 if len(front) == 0 { 45 return "", errors.New("could not determine metadata") 46 } 47 48 if err := yaml.Unmarshal([]byte(strings.Join(front, "\n")), out); err != nil { 49 return "", err 50 } 51 return strings.Join(body, "\n"), nil 52 }