diff --git a/Sources/Ink/API/MarkdownParser.swift b/Sources/Ink/API/MarkdownParser.swift index 4a2645e..bbea736 100644 --- a/Sources/Ink/API/MarkdownParser.swift +++ b/Sources/Ink/API/MarkdownParser.swift @@ -53,7 +53,7 @@ public struct MarkdownParser { do { if metadata == nil, fragments.isEmpty, reader.currentCharacter == "-" { if let parsedMetadata = try? Metadata.readOrRewind(using: &reader) { - metadata = parsedMetadata + metadata = parsedMetadata.applyingModifiers(modifiers) continue } } diff --git a/Sources/Ink/API/Modifier.swift b/Sources/Ink/API/Modifier.swift index ac427ac..24ecfa1 100644 --- a/Sources/Ink/API/Modifier.swift +++ b/Sources/Ink/API/Modifier.swift @@ -16,7 +16,8 @@ public struct Modifier { /// The type of input that each modifier is given, which both /// contains the HTML that was generated for a fragment, and - /// its raw Markdown representation. + /// its raw Markdown representation. Note that for metadata + /// targets, the two input arguments will be equivalent. public typealias Input = (html: String, markdown: Substring) /// The type of closure that Modifiers are based on. Each /// modifier is given a set of input, and is expected to return @@ -39,6 +40,8 @@ public struct Modifier { public extension Modifier { enum Target { + case metadataKeys + case metadataValues case blockquotes case codeBlocks case headings diff --git a/Sources/Ink/Internal/Metadata.swift b/Sources/Ink/Internal/Metadata.swift index ede16f4..4935f63 100644 --- a/Sources/Ink/Internal/Metadata.swift +++ b/Sources/Ink/Internal/Metadata.swift @@ -42,6 +42,26 @@ internal struct Metadata: Readable { throw Reader.Error() } + + func applyingModifiers(_ modifiers: ModifierCollection) -> Self { + var modified = self + + modifiers.applyModifiers(for: .metadataKeys) { modifier in + for (key, value) in modified.values { + let newKey = modifier.closure((key, Substring(key))) + modified.values[key] = nil + modified.values[newKey] = value + } + } + + modifiers.applyModifiers(for: .metadataValues) { modifier in + modified.values = modified.values.mapValues { value in + modifier.closure((value, Substring(value))) + } + } + + return modified + } } private extension Metadata { diff --git a/Tests/InkTests/MarkdownTests.swift b/Tests/InkTests/MarkdownTests.swift index a261cb3..b9fccbf 100644 --- a/Tests/InkTests/MarkdownTests.swift +++ b/Tests/InkTests/MarkdownTests.swift @@ -67,6 +67,29 @@ final class MarkdownTests: XCTestCase { XCTAssertEqual(markdown.html, "