a Micro Markdown frontmatter parser/printer for swift
0

Configure Feed

Select the types of activity you want to include in your feed.

Swift 100.0%
15 3 0

Clone this repository

https://tangled.org/woody.fm/swift-frontmatter-parsing https://tangled.org/did:plc:7lyflunvusddnum4d7tq7o3o
git@tangled.org:woody.fm/swift-frontmatter-parsing git@tangled.org:did:plc:7lyflunvusddnum4d7tq7o3o

For self-hosted knots, clone URLs may differ based on your setup.



README.md

FrontmatterParsing#

Parse and print Markdown documents with optional YAML front matter.

FrontmatterParsing is a small Swift package built on top of Yams. It turns a Markdown string into a MarkdownWithFrontMatter value and can print that value back to Markdown.

import FrontmatterParsing

struct Metadata: Codable, Equatable {
  var title: String
  var tags: [String]
}

let markdown = """
---
title: My Document
tags:
  - swift
  - markdown
---
# Hello
"""

let conversion = MarkdownWithFrontMatterConversion<Metadata>()
let document = try conversion.apply(markdown)

document.frontMatter?.title  // "My Document"
document.body?.hasPrefix("# Hello")

Installation#

Add the package to your Swift package dependencies:

.package(url: "https://tangled.org/woody.fm/swift-frontmatter-parsing", branch: "main")

Then add FrontmatterParsing to the targets that need it:

.target(
  name: "YourFeature",
  dependencies: [
    "FrontmatterParsing",
  ]
)

Parsing#

Use MarkdownWithFrontMatterConversion with any Codable front matter type:

struct PostFrontMatter: Codable, Equatable {
  var title: String
  var published: Bool
}

let conversion = MarkdownWithFrontMatterConversion<PostFrontMatter>()
let post = try conversion.apply(markdown)

let frontMatter = post.frontMatter
let body = post.body

If the input starts with a --- line, the package decodes everything up to the next --- line as YAML. The remaining text becomes the body.

let post = try conversion.apply(
  """
  ---
  title: Field Notes
  published: true
  ---
  Notes from the road.
  """
)

If the input does not start with a front matter delimiter, the whole string is treated as body text:

let document = try conversion.apply("Just Markdown")

document.frontMatter == nil
document.body == "Just Markdown"

An empty string returns an empty MarkdownWithFrontMatter value. A document with an opening delimiter but no closing delimiter throws MissingClosingFrontMatterDelimiterError.

Printing#

Use unapply to print a MarkdownWithFrontMatter value back to Markdown:

let rendered = try conversion.unapply(
  MarkdownWithFrontMatter(
    frontMatter: PostFrontMatter(title: "Field Notes", published: true),
    body: "Notes from the road."
  )
)

When front matter is present, it is encoded with YAMLEncoder and wrapped in --- delimiters. When the body is also present, it is printed after the closing delimiter.

Model#

The public model is intentionally small:

public struct MarkdownWithFrontMatter<FrontMatter> {
  public var frontMatter: FrontMatter?
  public var body: String?
}

This makes the package useful as a focused adapter around Markdown files in larger import, publishing, or note-taking pipelines.

Requirements#

This package currently targets Swift 6.0 or later, iOS 13 or later, macOS 12 or later, tvOS 13 or later, and watchOS 6 or later.

License#

Released under the MIT License.