Current section
Files
Jump to
Current section
Files
src/facet.gleam
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/string
pub type Error {
Empty
ParseError(msg: String)
}
/// The format of the frontmatter.
pub type Format {
TOML
JSON
YAML
}
/// The frontmatter content and format.
pub type Frontmatter {
Frontmatter(content: String, format: Format)
}
/// The Entire Document split between frontmatter and content.
pub type Document {
Document(frontmatter: Option(Frontmatter), content: String)
}
fn grab_frontmatter(
input: List(String),
frontmatter: List(String),
) -> Result(Document, Error) {
case input {
[] -> {
Error(ParseError("expected ending delimitor"))
}
["+++", ..rest] -> {
Ok(Document(
Some(Frontmatter(string.join(frontmatter, with: "\n"), TOML)),
string.join(rest, with: "\n"),
))
}
["}", ..rest] -> {
Ok(Document(
Some(Frontmatter(
string.join(list.append(frontmatter, ["}"]), with: "\n"),
JSON,
)),
string.join(rest, with: "\n"),
))
}
["---", ..rest] -> {
Ok(Document(
Some(Frontmatter(string.join(frontmatter, with: "\n"), YAML)),
string.join(rest, with: "\n"),
))
}
[line, ..rest] -> {
grab_frontmatter(rest, list.append(frontmatter, [line]))
}
}
}
/// Parse an input string and grab the frontmatter if it exists.
pub fn parse(in: String) -> Result(Document, Error) {
let lines =
in
|> string.split("\n")
case lines {
[] -> {
Error(Empty)
}
["+++", ..rest] -> {
grab_frontmatter(rest, [])
}
["{", ..rest] -> {
grab_frontmatter(rest, ["{"])
}
["---", ..rest] -> {
grab_frontmatter(rest, [])
}
rest -> {
Ok(Document(None, string.join(rest, with: "\n")))
}
}
}