Skip to content

Commit a4021f1

Browse files
authored
Trim snippet slice indentation (#348)
When trimming a slice out of a snippet, the slice may span some deeply nested scope that has indentation, so we don't want to take those lines as is, because they may be unnecessarily indented when presented as a slice. rdar://97696391
1 parent 3ce2bc9 commit a4021f1

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ struct RenderContentCompiler: MarkupVisitor {
224224
// Render only the slice.
225225
let lineRange = requestedLineRange.lowerBound..<min(requestedLineRange.upperBound, snippetMixin.lines.count)
226226
let lines = snippetMixin.lines[lineRange]
227-
return [RenderBlockContent.codeListing(syntax: snippetMixin.language, code: Array(lines), metadata: nil)]
227+
let minimumIndentation = lines.map { $0.prefix { $0.isWhitespace }.count }.min() ?? 0
228+
let trimmedLines = lines.map { String($0.dropFirst(minimumIndentation)) }
229+
return [RenderBlockContent.codeListing(syntax: snippetMixin.language, code: trimmedLines, metadata: nil)]
228230
} else {
229231
// Render the whole snippet with its explanation content.
230232
let docCommentContent = snippetEntity.markup.children.flatMap { self.visit($0) }

Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,9 @@ class RenderNodeTranslatorTests: XCTestCase {
955955
XCTAssertEqual(code.joined(separator: "\n"), """
956956
func foo() {}
957957
958-
middle()
958+
do {
959+
middle()
960+
}
959961
960962
func bar() {}
961963
""")
@@ -987,4 +989,29 @@ class RenderNodeTranslatorTests: XCTestCase {
987989
XCTAssertEqual(syntax, "swift")
988990
XCTAssertEqual(code, ["func foo() {}"])
989991
}
992+
993+
func testSnippetSliceTrimsIndentation() throws {
994+
let (bundle, context) = try testBundleAndContext(named: "Snippets")
995+
let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/Snippets/SliceIndentation", sourceLanguage: .swift)
996+
let article = try XCTUnwrap(context.entity(with: reference).semantic as? Article)
997+
var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: reference, source: nil)
998+
let renderNode = try XCTUnwrap(translator.visitArticle(article) as? RenderNode)
999+
let discussion = try XCTUnwrap(renderNode.primaryContentSections.first(where: { $0.kind == .content }) as? ContentRenderSection)
1000+
1001+
let lastCodeListingIndex = try XCTUnwrap(discussion.content.indices.last {
1002+
guard case .codeListing = discussion.content[$0] else {
1003+
return false
1004+
}
1005+
return true
1006+
})
1007+
1008+
guard case let .codeListing(syntax, code, _) = discussion.content[lastCodeListingIndex] else {
1009+
XCTFail("Missing snippet slice code block")
1010+
return
1011+
}
1012+
1013+
XCTAssertEqual(syntax, "swift")
1014+
XCTAssertEqual(code, ["middle()"])
1015+
1016+
}
9901017
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Slice Indentation
2+
3+
This article tests that slices trim extra indentation.
4+
5+
For example, in the following code:
6+
7+
```swift
8+
do {
9+
middle()
10+
}
11+
```
12+
13+
Slicing the line which contains `middle()` should look like this:
14+
15+
```swift
16+
middle()
17+
```
18+
19+
and not:
20+
21+
```swift
22+
middle()
23+
```
24+
25+
@Snippet(path: "Snippets/Snippets/MySnippet", slice: "middle")
26+
27+
<!-- Copyright (c) 2022 Apple Inc and the Swift Project authors. All Rights Reserved. -->

Tests/SwiftDocCTests/Test Bundles/Snippets.docc/Test-snippets.symbols.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
"lines": [
3131
"func foo() {}",
3232
"",
33-
"middle()",
33+
"do {",
34+
" middle()",
35+
"}",
3436
"",
3537
"func bar() {}"
3638
],
@@ -39,9 +41,13 @@
3941
0,
4042
1
4143
],
44+
"middle": [
45+
3,
46+
4
47+
],
4248
"bar": [
43-
4,
44-
5
49+
6,
50+
7
4551
]
4652
}
4753
},

0 commit comments

Comments
 (0)