Files
markdown-parsing/Sources/main.swift

115 lines
2.1 KiB
Swift

import Foundation
@preconcurrency import Parsing
var yamlString = """
---
author: Michael Housh
categories:
- HVAC
- General
- Programming
copy: true
draft: false
date: 2023-10-21
lastmod: 2023-10-21
image: banner.png
featuredImage: banner.png
tags:
- HVAC
- General
- Programming
title: "You Should Learn Markdown"
"""[...].utf8
struct YamlString: Parser {
var body: some Parser<Substring.UTF8View, String> {
OneOf {
Parse {
"\"".utf8
PrefixUpTo("\"".utf8)
"\"".utf8
}.map(.string)
Prefix { $0 != UInt8(ascii: "\n") }.map(.string)
}
}
}
struct YamlObject: Parser {
enum Value {
case array([String])
case boolean(Bool)
case date(YamlDate.Output)
case string(String)
}
var body: some Parser<Substring.UTF8View, [String: Value]> {
"---".utf8
Many(into: [String: Value]()) { (dict: inout [String: Value], pair: (String, Value)) in
dict[pair.0] = pair.1
} element: {
PrefixUpTo(":".utf8).map(.string)
":".utf8
OneOf {
Parse {
"\n".utf8
YamlArray()
}.map { Value.array($0) }
Parse {
Whitespace()
Bool.parser().map { Value.boolean($0) }
}
Parse {
Whitespace()
YamlDate().map { Value.date($0) }
}
Parse {
Whitespace()
YamlString().map { Value.string($0) }
}
}
} separator: {
"\n".utf8
}
}
}
struct YamlArray: Parser {
var body: some Parser<Substring.UTF8View, [String]> {
Many(into: [String]()) { array, string in
array.append(string)
} element: {
Whitespace(.horizontal)
"- ".utf8
Prefix { $0 != UInt8(ascii: "\n") }.map(.string)
} separator: {
"\n".utf8
}
}
}
struct YamlDate: Parser {
struct Output {
let year: Int
let month: Int
let day: Int
}
var body: some Parser<Substring.UTF8View, Output> {
Parse(.memberwise(Output.init)) {
Digits(4)
"-".utf8
Digits(2)
"-".utf8
Digits(2)
}
}
}
try print(YamlObject().parse(&yamlString))