Skip to content

Commit 0382b11

Browse files
add method to BasicBlockContainer that inherits the source ranges
1 parent 4379e5d commit 0382b11

File tree

6 files changed

+62
-3
lines changed

6 files changed

+62
-3
lines changed

Sources/Markdown/Base/Document.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ public extension Document {
6666

6767
/// Create a document from a sequence of block markup elements.
6868
init<Children: Sequence>(_ children: Children) where Children.Element == BlockMarkup {
69-
try! self.init(.document(parsedRange: nil, children.map { $0.raw.markup }))
69+
self.init(children, inheritSourceRange: false)
70+
}
71+
72+
init<Children: Sequence>(_ children: Children, inheritSourceRange: Bool) where Children.Element == BlockMarkup {
73+
let rawChildren = children.map { $0.raw.markup }
74+
let parsedRange = inheritSourceRange ? rawChildren.parsedRange : nil
75+
try! self.init(.document(parsedRange: parsedRange, rawChildren))
7076
}
7177

7278
// MARK: Visitation

Sources/Markdown/Base/RawMarkup.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,13 @@ fileprivate extension Sequence where Element == RawMarkup {
366366
return self.lazy.map { $0.subtreeCount }.reduce(0, +)
367367
}
368368
}
369+
370+
extension BidirectionalCollection where Element == RawMarkup {
371+
var parsedRange: SourceRange? {
372+
if let lowerBound = first?.parsedRange?.lowerBound, let upperBound = last?.parsedRange?.upperBound {
373+
return lowerBound..<upperBound
374+
} else {
375+
return nil
376+
}
377+
}
378+
}

Sources/Markdown/Block Nodes/Block Container Blocks/BlockQuote.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ public extension BlockQuote {
3030
// MARK: BasicBlockContainer
3131

3232
init<Children: Sequence>(_ children: Children) where Children.Element == BlockMarkup {
33-
try! self.init(.blockQuote(parsedRange: nil, children.map { $0.raw.markup }))
33+
self.init(children, inheritSourceRange: false)
34+
}
35+
36+
init<Children: Sequence>(_ children: Children, inheritSourceRange: Bool) where Children.Element == BlockMarkup {
37+
let rawChildren = children.map { $0.raw.markup }
38+
let parsedRange = inheritSourceRange ? rawChildren.parsedRange : nil
39+
try! self.init(.blockQuote(parsedRange: parsedRange, rawChildren))
3440
}
3541

3642
// MARK: Visitation

Sources/Markdown/Block Nodes/Block Container Blocks/CustomBlock.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ public struct CustomBlock: BlockMarkup, BasicBlockContainer {
3030

3131
public extension CustomBlock {
3232
init<Children: Sequence>(_ children: Children) where Children.Element == BlockMarkup {
33-
try! self.init(.customBlock(parsedRange: nil, children.map { $0.raw.markup }))
33+
self.init(children, inheritSourceRange: false)
34+
}
35+
36+
init<Children: Sequence>(_ children: Children, inheritSourceRange: Bool) where Children.Element == BlockMarkup {
37+
let rawChildren = children.map { $0.raw.markup }
38+
let parsedRange = inheritSourceRange ? rawChildren.parsedRange : nil
39+
try! self.init(.customBlock(parsedRange: parsedRange, rawChildren))
3440
}
3541

3642
// MARK: Visitation

Sources/Markdown/Structural Restrictions/BasicBlockContainer.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
public protocol BasicBlockContainer: BlockContainer {
1313
/// Create this element from a sequence of block markup elements.
1414
init<Children: Sequence>(_ children: Children) where Children.Element == BlockMarkup
15+
16+
/// Create this element from a sequence of block markup elements, and optionally inherit the source range from those elements.
17+
init<Children: Sequence>(_ children: Children, inheritSourceRange: Bool) where Children.Element == BlockMarkup
1518
}
1619

1720
// MARK: - Public API
@@ -21,4 +24,14 @@ extension BasicBlockContainer {
2124
public init(_ children: BlockMarkup...) {
2225
self.init(children)
2326
}
27+
28+
/// Create this element with a sequence of block markup elements, and optionally inherit the source range from those elements.
29+
public init(_ children: BlockMarkup..., inheritSourceRange: Bool) {
30+
self.init(children, inheritSourceRange: inheritSourceRange)
31+
}
32+
33+
/// Default implementation of `init(_:inheritSourceRange:)` that discards the `inheritSourceRange` parameter.
34+
public init<Children: Sequence>(_ children: Children, inheritSourceRange: Bool) where Children.Element == BlockMarkup {
35+
self.init(children)
36+
}
2437
}

Tests/MarkdownTests/Structural Restrictions/BasicBlockContainerTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,22 @@ final class BasicBlockContainerTests: XCTestCase {
110110
"""
111111
XCTAssertEqual(expectedDump, newDocument.debugDescription())
112112
}
113+
114+
func testInheritSourceRange() throws {
115+
let source = "Note: This is just a paragraph."
116+
let fakeFileLocation = URL(fileURLWithPath: "/path/to/some-file.md")
117+
let document = Document(parsing: source, source: fakeFileLocation)
118+
let paragraph = try XCTUnwrap(document.child(at: 0) as? Paragraph)
119+
120+
// this block quote has no source information, but its children do
121+
let blockQuote = BlockQuote(paragraph, inheritSourceRange: true)
122+
123+
let expectedRootDump = """
124+
BlockQuote @/path/to/some-file.md:1:1-/path/to/some-file.md:1:32
125+
└─ Paragraph @/path/to/some-file.md:1:1-/path/to/some-file.md:1:32
126+
└─ Text @/path/to/some-file.md:1:1-/path/to/some-file.md:1:32 "Note: This is just a paragraph."
127+
"""
128+
129+
XCTAssertEqual(expectedRootDump, blockQuote.debugDescription(options: .printSourceLocations))
130+
}
113131
}

0 commit comments

Comments
 (0)