Skip to content

Commit 93a2982

Browse files
authored
Add an anchor to TaskGroupRenderSection (#883)
rdar://125967110 rdar://124536381
1 parent 0c546df commit 93a2982

File tree

6 files changed

+42
-11
lines changed

6 files changed

+42
-11
lines changed

Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,8 @@ public struct RenderNodeTranslator: SemanticVisitor {
996996
abstract: nil,
997997
discussion: nil,
998998
identifiers: group.references.map(\.url.absoluteString),
999-
generated: true
999+
generated: true,
1000+
anchor: urlReadableFragment(group.title)
10001001
)
10011002
}
10021003
}
@@ -1148,7 +1149,8 @@ public struct RenderNodeTranslator: SemanticVisitor {
11481149
default: break
11491150
}
11501151
return nil
1151-
}
1152+
},
1153+
anchor: group.heading.map { urlReadableFragment($0.plainText) } ?? "Topics"
11521154
)
11531155

11541156
// rdar://74617294 If a task group doesn't have any symbol or external links it shouldn't be rendered
@@ -1608,7 +1610,8 @@ public struct RenderNodeTranslator: SemanticVisitor {
16081610
title: group.heading,
16091611
abstract: nil,
16101612
discussion: nil,
1611-
identifiers: group.references.map({ $0.url!.absoluteString })
1613+
identifiers: group.references.map({ $0.url!.absoluteString }),
1614+
anchor: urlReadableFragment(group.heading)
16121615
)
16131616
}
16141617
} ?? .init(defaultValue: [])

Sources/SwiftDocC/Model/Rendering/Symbol/TaskGroupRenderSection.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -36,6 +36,8 @@ public struct TaskGroupRenderSection: RenderSection, Equatable {
3636
public let identifiers: [String]
3737
/// If true, this is an automatically generated group. If false, this is an authored group.
3838
public let generated: Bool
39+
/// An optional anchor that can be used to link to the task group.
40+
public let anchor: String?
3941

4042
/// Creates a new task group.
4143
/// - Parameters:
@@ -44,17 +46,19 @@ public struct TaskGroupRenderSection: RenderSection, Equatable {
4446
/// - discussion: An optional discussion for the section.
4547
/// - identifiers: A list of topic-graph references.
4648
/// - generated: If `true`, this is an automatically generated group. If `false`, this is an authored group.
47-
public init(title: String?, abstract: [RenderInlineContent]?, discussion: RenderSection?, identifiers: [String], generated: Bool = false) {
49+
/// - anchor: An optional anchor that can be used to link to the task group.
50+
public init(title: String?, abstract: [RenderInlineContent]?, discussion: RenderSection?, identifiers: [String], generated: Bool = false, anchor: String? = nil) {
4851
self.title = title
4952
self.abstract = abstract
5053
self.identifiers = identifiers
5154
self.generated = generated
55+
self.anchor = anchor ?? title.map(urlReadableFragment)
5256
self.discussion = discussion
5357
}
5458

5559
/// The list of keys you use to encode or decode this section.
5660
private enum CodingKeys: CodingKey {
57-
case title, abstract, discussion, identifiers, generated
61+
case title, abstract, discussion, identifiers, generated, anchor
5862
}
5963

6064
public func encode(to encoder: Encoder) throws {
@@ -67,6 +71,7 @@ public struct TaskGroupRenderSection: RenderSection, Equatable {
6771
if generated {
6872
try container.encode(generated, forKey: .generated)
6973
}
74+
try container.encodeIfPresent(anchor, forKey: .anchor)
7075
}
7176

7277
public init(from decoder: Decoder) throws {
@@ -79,6 +84,7 @@ public struct TaskGroupRenderSection: RenderSection, Equatable {
7984
decoder.registerReferences(identifiers)
8085

8186
generated = try container.decodeIfPresent(Bool.self, forKey: .generated) ?? false
87+
anchor = try container.decodeIfPresent(String.self, forKey: .anchor)
8288
discussion = (try container.decodeIfPresent(CodableContentSection.self, forKey: .discussion)).map { $0.section }
8389
}
8490
}
@@ -91,6 +97,7 @@ extension TaskGroupRenderSection {
9197
self.abstract = nil
9298
self.identifiers = group.references.map({ $0.absoluteString })
9399
self.generated = true
100+
self.anchor = group.title.map(urlReadableFragment)
94101
self.discussion = nil
95102
}
96103
}

Sources/SwiftDocC/SwiftDocC.docc/Resources/RenderNode.spec.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"openapi": "3.0.0",
33
"info": {
44
"description": "Render Node API",
5-
"version": "0.4.1",
5+
"version": "0.4.2",
66
"title": "Render Node API"
77
},
88
"paths": { },
@@ -2704,6 +2704,9 @@
27042704
},
27052705
"generated": {
27062706
"type": "boolean"
2707+
},
2708+
"anchor": {
2709+
"type": "string"
27072710
}
27082711
}
27092712
},

Tests/SwiftDocCTests/Indexing/NavigatorIndexTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,8 @@ Root
776776
abstract: section.abstract,
777777
discussion: section.discussion,
778778
identifiers: identifiers,
779-
generated: section.generated)
779+
generated: section.generated,
780+
anchor: section.title.map(urlReadableFragment))
780781
}
781782
return section
782783
}

Tests/SwiftDocCTests/Infrastructure/DocumentationContext/DocumentationContextTests.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3100,7 +3100,7 @@ let expected = """
31003100
31013101
## Topics
31023102
3103-
### Some topic section
3103+
### Some, topic - section!
31043104
31053105
- <doc:Third>
31063106
"""),
@@ -3176,6 +3176,22 @@ let expected = """
31763176
let converter = DocumentationNodeConverter(bundle: bundle, context: context)
31773177
let renderNode = try converter.convert(entity, at: nil)
31783178

3179+
XCTAssertEqual(renderNode.topicSections.map(\.anchor), [
3180+
"Another-topic-section"
3181+
])
3182+
3183+
let firstReference = try XCTUnwrap(context.knownPages.first(where: { $0.lastPathComponent == "First" }))
3184+
let firstRenderNode = try converter.convert(context.entity(with: firstReference), at: nil)
3185+
XCTAssertEqual(firstRenderNode.topicSections.map(\.anchor), [
3186+
"Topics"
3187+
])
3188+
3189+
let secondReference = try XCTUnwrap(context.knownPages.first(where: { $0.lastPathComponent == "Second" }))
3190+
let secondRenderNode = try converter.convert(context.entity(with: secondReference), at: nil)
3191+
XCTAssertEqual(secondRenderNode.topicSections.map(\.anchor), [
3192+
"Some-topic-section"
3193+
])
3194+
31793195
let overviewSection = try XCTUnwrap(renderNode.primaryContentSections.first as? ContentRenderSection)
31803196
guard case .unorderedList(let unorderedList) = overviewSection.content.dropFirst().first else {
31813197
XCTFail("The first element of the Overview section (after the heading) should be an unordered list")

Tests/SwiftDocCTests/Model/RenderNodeDiffingBundleTests.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2023 Apple Inc. and the Swift project authors
4+
Copyright (c) 2023-2024 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -69,7 +69,8 @@ class RenderNodeDiffingBundleTests: XCTestCase {
6969
discussion: nil,
7070
identifiers: ["doc://org.swift.docc.example/tutorials/Test-Bundle/TestTutorial",
7171
"doc://org.swift.docc.example/tutorials/Test-Bundle/TestTutorial2"],
72-
generated: false)))
72+
generated: false,
73+
anchor: "Tutorials")))
7374
assertDifferences(differences,
7475
contains: expectedDiff,
7576
valueType: TaskGroupRenderSection.self)

0 commit comments

Comments
 (0)