diff --git a/frontmatter.lux b/frontmatter.lux deleted file mode 100644 index 070478b..0000000 --- a/frontmatter.lux +++ /dev/null @@ -1,79 +0,0 @@ -// YAML-like frontmatter parser -// Parses the --- delimited frontmatter block from markdown files - -pub type Frontmatter = - | Frontmatter(String, String, String, String) - // title date desc tagsRaw - -pub type ParseResult = - | ParseResult(Frontmatter, String) - // front body - -pub fn parse(content: String): ParseResult = { - let lines = String.lines(content); - // Skip first --- line, collect key: value pairs until next --- - let result = List.fold(lines, (false, false, "", "", "", "", ""), fn(acc: (Bool, Bool, String, String, String, String, String), line: String): (Bool, Bool, String, String, String, String, String) => { - let inFront = acc.0; - let pastFront = acc.1; - let title = acc.2; - let date = acc.3; - let desc = acc.4; - let tags = acc.5; - let body = acc.6; - if pastFront then - (inFront, pastFront, title, date, desc, tags, body + line + "\n") - else if String.trim(line) == "---" then - if inFront then - // End of frontmatter - (false, true, title, date, desc, tags, body) - else - // Start of frontmatter - (true, false, title, date, desc, tags, body) - else if inFront then { - // Parse key: value - match String.indexOf(line, ": ") { - Some(idx) => { - let key = String.trim(String.substring(line, 0, idx)); - let rawVal = String.trim(String.substring(line, idx + 2, String.length(line))); - // Strip surrounding quotes if present - let val = if String.startsWith(rawVal, "\"") then - String.substring(rawVal, 1, String.length(rawVal) - 1) - else - rawVal; - if key == "title" then - (inFront, pastFront, val, date, desc, tags, body) - else if key == "date" then - (inFront, pastFront, title, val, desc, tags, body) - else if key == "description" then - (inFront, pastFront, title, date, val, tags, body) - else if key == "tags" then - (inFront, pastFront, title, date, desc, val, body) - else - (inFront, pastFront, title, date, desc, tags, body) - }, - None => (inFront, pastFront, title, date, desc, tags, body) - } - } else - (inFront, pastFront, title, date, desc, tags, body) - }); - let front = Frontmatter(result.2, result.3, result.4, result.5); - ParseResult(front, result.6) -} - -pub fn getTitle(f: Frontmatter): String = - match f { Frontmatter(t, _, _, _) => t } - -pub fn getDate(f: Frontmatter): String = - match f { Frontmatter(_, d, _, _) => d } - -pub fn getDesc(f: Frontmatter): String = - match f { Frontmatter(_, _, d, _) => d } - -pub fn getTagsRaw(f: Frontmatter): String = - match f { Frontmatter(_, _, _, t) => t } - -pub fn getTags(f: Frontmatter): List = - match f { Frontmatter(_, _, _, t) => - if t == "" then [] - else String.split(t, " ") - } diff --git a/lux.lock b/lux.lock index 1fe8235..ae25a6b 100644 --- a/lux.lock +++ b/lux.lock @@ -1,5 +1,10 @@ # This file is auto-generated by lux pkg. Do not edit manually. +[[package]] +name = "frontmatter" +version = "0.1.0" +source = "path:../../packages/frontmatter" + [[package]] name = "markdown" version = "0.1.0" diff --git a/lux.toml b/lux.toml index 24cf307..97adc25 100644 --- a/lux.toml +++ b/lux.toml @@ -5,3 +5,4 @@ description = "A Lux project" [dependencies] markdown = { version = "0.1.0", path = "../../packages/markdown" } +frontmatter = { version = "0.1.0", path = "../../packages/frontmatter" } diff --git a/main.lux b/main.lux index 7aebe94..679b937 100644 --- a/main.lux +++ b/main.lux @@ -1,20 +1,12 @@ import markdown +import frontmatter type SiteConfig = | SiteConfig(String, String, String, String, String, String, String) -type Frontmatter = - | Frontmatter(String, String, String, String) - -type ParseResult = - | ParseResult(Frontmatter, String) - type Page = | Page(String, String, String, String, String) -type FMState = - | FMState(Bool, Bool, String, String, String, String, String) - type TagEntry = | TagEntry(String, String, String, String, String) @@ -103,49 +95,6 @@ fn cfgStaticDir(c: SiteConfig): String = SiteConfig(_, _, _, _, _, _, sd) => sd, } -fn fmFoldLine(acc: FMState, line: String): FMState = - match acc { - FMState(inFront, pastFront, title, date, desc, tags, body) => if pastFront then FMState(inFront, pastFront, title, date, desc, tags, body + line + " -") else if String.trim(line) == "---" then if inFront then FMState(false, true, title, date, desc, tags, body) else FMState(true, false, title, date, desc, tags, body) else if inFront then match String.indexOf(line, ": ") { - Some(idx) => { - let key = String.trim(String.substring(line, 0, idx)) - let rawVal = String.trim(String.substring(line, idx + 2, String.length(line))) - let val = if String.startsWith(rawVal, "\"") then String.substring(rawVal, 1, String.length(rawVal) - 1) else rawVal - if key == "title" then FMState(inFront, pastFront, val, date, desc, tags, body) else if key == "date" then FMState(inFront, pastFront, title, val, desc, tags, body) else if key == "description" then FMState(inFront, pastFront, title, date, val, tags, body) else if key == "tags" then FMState(inFront, pastFront, title, date, desc, val, body) else acc -}, - None => acc, -} else acc, -} - -fn parseFrontmatter(content: String): ParseResult = { - let lines = String.lines(content) - let init = FMState(false, false, "", "", "", "", "") - let result = List.fold(lines, init, fmFoldLine) - match result { - FMState(_, _, title, date, desc, tags, body) => ParseResult(Frontmatter(title, date, desc, tags), body), -} -} - -fn fmTitle(f: Frontmatter): String = - match f { - Frontmatter(t, _, _, _) => t, -} - -fn fmDate(f: Frontmatter): String = - match f { - Frontmatter(_, d, _, _) => d, -} - -fn fmTagsRaw(f: Frontmatter): String = - match f { - Frontmatter(_, _, _, t) => t, -} - -fn fmTags(f: Frontmatter): List = - match f { - Frontmatter(_, _, _, t) => if t == "" then [] else String.split(t, " "), -} - fn pgDate(p: Page): String = match p { Page(d, _, _, _, _) => d, @@ -262,18 +211,15 @@ fn htmlTagPage(tagName: String, postsHtml: String): String = "
{ - let title = fmTitle(front) - let date = fmDate(front) - let tags = fmTagsRaw(front) + let doc = frontmatter.parse(raw) + let title = frontmatter.title(doc) + let date = frontmatter.date(doc) + let tags = frontmatter.getOrDefault(doc, "tags", "") + let body = frontmatter.body(doc) let htmlContent = convertMd(body) let filename = basename(path) let slug = slugFromFilename(filename) Page(date, title, slug, tags, htmlContent) -}, -} } fn mapParseFiles(dir: String, files: List): List with {File} = @@ -384,10 +330,8 @@ fn writeTagPages(outputDir: String, allTagEntries: List, siteTitle: St fn renderSnippetFile(snippetDir: String, filename: String): String with {File} = { let raw = File.read(snippetDir + "/" + filename) - let parsed = parseFrontmatter(raw) - match parsed { - ParseResult(_, body) => htmlSnippetCard(convertMd(body)), -} + let doc = frontmatter.parse(raw) + htmlSnippetCard(convertMd(frontmatter.body(doc))) } fn renderSnippets(snippetDir: String, files: List): List with {File} =