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:
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user