2019-11-06 12:27:02 +01:00
|
|
|
package frontmatter
|
|
|
|
|
|
|
|
import (
|
2020-03-11 23:54:46 +01:00
|
|
|
"fmt"
|
2022-08-26 18:06:13 +02:00
|
|
|
"runtime"
|
2019-11-06 12:27:02 +01:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"gopkg.in/yaml.v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Frontmatter encapsulates cheatsheet frontmatter data
|
|
|
|
type Frontmatter struct {
|
|
|
|
Tags []string
|
|
|
|
Syntax string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse parses cheatsheet frontmatter
|
|
|
|
func Parse(markdown string) (string, Frontmatter, error) {
|
|
|
|
|
2022-08-26 18:06:13 +02:00
|
|
|
// determine the appropriate line-break for the platform
|
|
|
|
linebreak := "\n"
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
linebreak = "\r\n"
|
|
|
|
}
|
|
|
|
|
2019-11-06 12:27:02 +01:00
|
|
|
// specify the frontmatter delimiter
|
2022-08-26 18:06:13 +02:00
|
|
|
delim := fmt.Sprintf("---%s", linebreak)
|
2019-11-06 12:27:02 +01:00
|
|
|
|
|
|
|
// initialize a frontmatter struct
|
|
|
|
var fm Frontmatter
|
|
|
|
|
|
|
|
// if the markdown does not contain frontmatter, pass it through unmodified
|
|
|
|
if !strings.HasPrefix(markdown, delim) {
|
2022-08-26 18:06:13 +02:00
|
|
|
return markdown, fm, nil
|
2019-11-06 12:27:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise, split the frontmatter and cheatsheet text
|
|
|
|
parts := strings.SplitN(markdown, delim, 3)
|
|
|
|
|
2020-03-11 23:54:46 +01:00
|
|
|
// return an error if the frontmatter parses into the wrong number of parts
|
|
|
|
if len(parts) != 3 {
|
|
|
|
return markdown, fm, fmt.Errorf("failed to delimit frontmatter")
|
|
|
|
}
|
|
|
|
|
|
|
|
// return an error if the YAML cannot be unmarshalled
|
|
|
|
if err := yaml.Unmarshal([]byte(parts[1]), &fm); err != nil {
|
|
|
|
return markdown, fm, fmt.Errorf("failed to unmarshal frontmatter: %v", err)
|
|
|
|
}
|
|
|
|
|
2022-08-26 18:06:13 +02:00
|
|
|
return parts[2], fm, nil
|
2019-11-06 12:27:02 +01:00
|
|
|
}
|