feat: Working yaml block parser, but does need to parse the end of the yaml block before parsing markdown contents.

This commit is contained in:
2025-02-18 14:40:31 -05:00
parent 659bd8b797
commit 88fc0c9688

View File

@@ -1,7 +1,8 @@
import Foundation import Foundation
@preconcurrency import Parsing @preconcurrency import Parsing
let yamlString = """ var yamlString = """
---
author: Michael Housh author: Michael Housh
categories: categories:
- HVAC - HVAC
@@ -18,128 +19,96 @@ tags:
- General - General
- Programming - Programming
title: "You Should Learn Markdown" title: "You Should Learn Markdown"
""" """[...].utf8
_ = """ struct YamlString: Parser {
series:
- General
title: "You Should Learn Markdown"
slug: "you-should-learn-markdown"
"""
struct SimpleYamlValue: Parser { var body: some Parser<Substring.UTF8View, String> {
enum Output: Equatable {
case array([String])
case bool(Bool)
case date(year: Int, month: Int, day: Int)
case string(String)
}
var body: some Parser<Substring.UTF8View, Output> {
OneOf { OneOf {
// YamlList().map { Output.array($0) }
DateParser()
Bool.parser().map(.case(Output.bool))
PrefixUpTo("\n".utf8).map(.string).map(.case(Output.string))
Rest().map(.string).map(.case(Output.string))
}
}
struct DateParser: Parser {
var body: some Parser<Substring.UTF8View, Output> {
Parse { Parse {
Digits(4) "\"".utf8
"-".utf8 PrefixUpTo("\"".utf8)
Digits(2) "\"".utf8
"-".utf8 }.map(.string)
Digits(2)
}.map(.case(Output.date)) Prefix { $0 != UInt8(ascii: "\n") }.map(.string)
} }
} }
} }
struct SimpleYamlParser: Parser { struct YamlObject: Parser {
typealias Output = [String: SimpleYamlValue.Output] enum Value {
case array([String])
case boolean(Bool)
case date(YamlDate.Output)
case string(String)
}
var body: some Parser<Substring.UTF8View, Output> { var body: some Parser<Substring.UTF8View, [String: Value]> {
Many(into: Output()) { (dict: inout Output, pair: (String, SimpleYamlValue.Output)) in "---".utf8
let (key, value) = pair Many(into: [String: Value]()) { (dict: inout [String: Value], pair: (String, Value)) in
dict[key] = value dict[pair.0] = pair.1
} element: { } element: {
// Parses a key and array. PrefixUpTo(":".utf8).map(.string)
":".utf8
OneOf { OneOf {
Parse { Parse {
PrefixUpTo(":".utf8).map(.string) "\n".utf8
":\n".utf8 YamlArray()
Many(into: [String]()) { array, string in }.map { Value.array($0) }
array.append(string)
} element: {
From(.substring) { Whitespace() }
"-".utf8
From(.substring) { Whitespace() }
PrefixUpTo("\n".utf8).map(.string)
} separator: {
"\n".utf8
}
// terminator: {
// OneOf {
// Peek { PrefixUpTo(":".utf8) }
// End()
// }
// }
}
.map { ($0.0, SimpleYamlValue.Output.array($0.1)) }
// Parse a key and a single value.
Parse { Parse {
PrefixUpTo(":".utf8).map(.string)
":".utf8
Whitespace() Whitespace()
SimpleYamlValue() Bool.parser().map { Value.boolean($0) }
}
Parse {
Whitespace()
YamlDate().map { Value.date($0) }
}
Parse {
Whitespace()
YamlString().map { Value.string($0) }
} }
} }
} separator: { } separator: {
"\n".utf8 "\n".utf8
} terminator: {
End()
} }
} }
} }
let simpleYamlString = #""" struct YamlArray: Parser {
author: Michael Housh var body: some Parser<Substring.UTF8View, [String]> {
copy: true Many(into: [String]()) { array, string in
draft: false array.append(string)
date: 2023-10-21 } element: {
lastmod: 2023-10-21 Whitespace(.horizontal)
image: banner.png "- ".utf8
featuredImage: banner.png Prefix { $0 != UInt8(ascii: "\n") }.map(.string)
test: } separator: {
- HVAC "\n".utf8
- General }
- Programming }
foo: Bar
"""#
var keyedList = """
test:
- HVAC
- General
- Programming
foo: Bar
"""[...].utf8
// let parsedList = try keyedListParser.parse(&keyedList)
// print(parsedList)
let parsed = try SimpleYamlParser().parse(simpleYamlString[...].utf8)
// let parsed = try SimpleYamlParser().parse(yamlString[...].utf8)
for (key, value) in parsed {
print("\(key): \(value)")
} }
// assert(parsed.keys.count == 10) struct YamlDate: Parser {
struct Output {
let year: Int
let month: Int
let day: Int
}
// try print(SimpleYamlParser().parse(simpleYamlString[...].utf8)) var body: some Parser<Substring.UTF8View, Output> {
Parse(.memberwise(Output.init)) {
Digits(4)
"-".utf8
Digits(2)
"-".utf8
Digits(2)
}
}
}
try print(YamlObject().parse(&yamlString))