Skip to content

Commit ff69522

Browse files
committed
Update documentation and tests
1 parent 94770f6 commit ff69522

19 files changed

+631
-19
lines changed

Sources/SwiftDocC/Infrastructure/Topic Graph/AutomaticCuration.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,10 @@ public struct AutomaticCuration {
123123
renderContext: RenderContext?,
124124
renderer: DocumentationContentRenderer
125125
) throws -> TaskGroup? {
126-
if let automaticSeeAlsoOption = node.options?.automaticSeeAlso ?? context.options?.automaticSeeAlso {
127-
guard automaticSeeAlsoOption.behavior == .siblingPages else {
126+
if let automaticSeeAlsoOption = node.options?.automaticSeeAlsoBehavior
127+
?? context.options?.automaticSeeAlsoBehavior
128+
{
129+
guard automaticSeeAlsoOption == .siblingPages else {
128130
return nil
129131
}
130132
}

Sources/SwiftDocC/Model/DocumentationMarkup.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ struct DocumentationMarkup {
146146
// Found deprecation notice in the abstract.
147147
deprecation = MarkupContainer(directive.children)
148148
return
149-
} else if directive.name == Comment.directiveName || directive.name == Metadata.directiveName {
149+
} else if directive.name == Comment.directiveName || directive.name == Metadata.directiveName || directive.name == Options.directiveName {
150150
// These directives don't affect content so they shouldn't break us out of
151151
// the automatic abstract section.
152152
return

Sources/SwiftDocC/Model/DocumentationNode.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ public struct DocumentationNode {
617617
self.docChunks = [DocumentationChunk(source: .documentationExtension, markup: articleMarkup)]
618618
self.markup = articleMarkup
619619
self.isVirtual = false
620+
self.options = article.options[.local]
620621

621622
updateAnchorSections()
622623
}

Sources/SwiftDocC/Model/Rendering/RenderNode.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ public struct RenderNode: VariantContainer {
162162
/// The variants of the primary content sections of the node, which are the main sections of a reference documentation node.
163163
public var primaryContentSectionsVariants: [VariantCollection<CodableContentSection?>] = []
164164

165+
/// The visual style that should be used when rendering this page's Topics section.
165166
public var topicSectionsStyle: TopicsSectionStyle
166167

167168
/// The default Topics sections of this documentation node, which contain links to useful related documentation nodes.

Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,10 +1043,10 @@ public struct RenderNodeTranslator: SemanticVisitor {
10431043

10441044
private func shouldCreateAutomaticRoleHeading(for node: DocumentationNode) -> Bool {
10451045
var shouldCreateAutomaticRoleHeading = true
1046-
if let automaticTitleHeadingOption = node.options?.automaticTitleHeading
1047-
?? context.options?.automaticTitleHeading
1046+
if let automaticTitleHeadingOption = node.options?.automaticTitleHeadingBehavior
1047+
?? context.options?.automaticTitleHeadingBehavior
10481048
{
1049-
shouldCreateAutomaticRoleHeading = automaticTitleHeadingOption.behavior == .pageKind
1049+
shouldCreateAutomaticRoleHeading = automaticTitleHeadingOption == .pageKind
10501050
}
10511051

10521052
return shouldCreateAutomaticRoleHeading
@@ -1057,7 +1057,7 @@ public struct RenderNodeTranslator: SemanticVisitor {
10571057
if let topicsSectionStyleOption = node.options?.topicsVisualStyle
10581058
?? context.options?.topicsVisualStyle
10591059
{
1060-
topicsVisualStyleOption = topicsSectionStyleOption.style
1060+
topicsVisualStyleOption = topicsSectionStyleOption
10611061
} else {
10621062
topicsVisualStyleOption = .list
10631063
}

Sources/SwiftDocC/Model/Rendering/TopicsSectionStyle.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,20 @@
1111
extension RenderNode {
1212
/// The rendering style of the topics section.
1313
public enum TopicsSectionStyle: String, Codable {
14+
/// A list of the page's topics, including their full declaration and abstract.
1415
case list
16+
17+
/// A grid of items based on the card image for each page.
18+
///
19+
/// Includes each page’s title and card image but excludes their abstracts.
1520
case compactGrid
21+
22+
/// A grid of items based on the card image for each page.
23+
///
24+
/// Unlike ``compactGrid``, this style includes the abstract for each page.
1625
case detailedGrid
26+
27+
/// Do not show child pages anywhere on the page.
1728
case hidden
1829
}
1930
}

Sources/SwiftDocC/Semantics/DirectiveInfrastructure/DirectiveIndex.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct DirectiveIndex {
1717
Snippet.self,
1818
DeprecationSummary.self,
1919
Row.self,
20+
Options.self,
2021
]
2122

2223
private static let topLevelTutorialDirectives: [AutomaticDirectiveConvertible.Type] = [

Sources/SwiftDocC/Semantics/Options/AutomaticSeeAlso.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@
1111
import Foundation
1212
import Markdown
1313

14+
/// A directive for specifying Swift-DocC's automatic behavior when generating a page's
15+
/// See Also section.
1416
public class AutomaticSeeAlso: Semantic, AutomaticDirectiveConvertible {
1517
public let originalMarkup: BlockDirective
1618

19+
/// The specified behavior for automatic See Also section generation.
1720
@DirectiveArgumentWrapped(name: .unnamed)
1821
public private(set) var behavior: Behavior
1922

23+
/// A behavior for automatic See Also section generation.
2024
public enum Behavior: String, CaseIterable, DirectiveArgumentValueConvertible {
25+
/// A See Also section will not be automatically created.
2126
case disabled
2227

28+
/// A See Also section will be automatically created based on the page's siblings.
2329
case siblingPages
2430
}
2531

Sources/SwiftDocC/Semantics/Options/AutomaticTitleHeading.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,23 @@
1111
import Foundation
1212
import Markdown
1313

14+
/// A directive for specifying Swift-DocC's automatic behavior when generating a page's
15+
/// title heading.
16+
///
17+
/// A title heading is also known as a page eyebrow or kicker.
1418
public class AutomaticTitleHeading: Semantic, AutomaticDirectiveConvertible {
1519
public let originalMarkup: BlockDirective
1620

21+
/// The specified behavior for automatic title heading generation.
1722
@DirectiveArgumentWrapped(name: .unnamed)
1823
public private(set) var behavior: Behavior
1924

25+
/// A behavior for automatic title heading generation.
2026
public enum Behavior: String, CaseIterable, DirectiveArgumentValueConvertible {
27+
/// No title heading should be created for the page.
2128
case disabled
2229

30+
/// A title heading based on the page's kind should be automatically created.
2331
case pageKind
2432
}
2533

Sources/SwiftDocC/Semantics/Options/Options.swift

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,53 @@
1111
import Foundation
1212
import Markdown
1313

14+
/// A directive that specifies various options for the page.
1415
public class Options: Semantic, AutomaticDirectiveConvertible {
1516
public let originalMarkup: BlockDirective
1617

18+
/// Whether the options in this Options directive should apply locally to the page
19+
/// or globally to the DocC catalog.
1720
@DirectiveArgumentWrapped
1821
public private(set) var scope: Scope = .local
1922

2023
@ChildDirective
21-
public private(set) var automaticSeeAlso: AutomaticSeeAlso? = nil
24+
public private(set) var _automaticSeeAlso: AutomaticSeeAlso? = nil
2225

2326
@ChildDirective
24-
public private(set) var automaticTitleHeading: AutomaticTitleHeading? = nil
27+
public private(set) var _automaticTitleHeading: AutomaticTitleHeading? = nil
2528

2629
@ChildDirective
27-
public private(set) var topicsVisualStyle: TopicsVisualStyle? = nil
30+
public private(set) var _topicsVisualStyle: TopicsVisualStyle? = nil
2831

32+
/// If given, the authored behavior for automatic See Also section generation.
33+
public var automaticSeeAlsoBehavior: AutomaticSeeAlso.Behavior? {
34+
return _automaticSeeAlso?.behavior
35+
}
36+
37+
/// If given, the authored behavior for automatic Title Heading generation.
38+
public var automaticTitleHeadingBehavior: AutomaticTitleHeading.Behavior? {
39+
return _automaticTitleHeading?.behavior
40+
}
41+
42+
/// If given, the authored style for a page's Topics section.
43+
public var topicsVisualStyle: TopicsVisualStyle.Style? {
44+
return _topicsVisualStyle?.style
45+
}
46+
47+
/// A scope for the options provided by an Options directive.
2948
public enum Scope: String, CaseIterable, DirectiveArgumentValueConvertible {
49+
/// The directive should only affect the current page.
3050
case local
3151

52+
/// The directive should affect all pages in the current DocC catalog.
3253
case global
3354
}
3455

3556
static var keyPaths: [String : AnyKeyPath] = [
3657
"scope" : \Options._scope,
37-
"automaticSeeAlso" : \Options._automaticSeeAlso,
38-
"automaticTitleHeading" : \Options._automaticTitleHeading,
39-
"topicsVisualStyle" : \Options._topicsVisualStyle,
58+
"_automaticSeeAlso" : \Options.__automaticSeeAlso,
59+
"_automaticTitleHeading" : \Options.__automaticTitleHeading,
60+
"_topicsVisualStyle" : \Options.__topicsVisualStyle,
4061
]
4162

4263
@available(*, deprecated, message: "Do not call directly. Required for 'AutomaticDirectiveConvertible'.")

Sources/SwiftDocC/Semantics/Options/TopicsVisualStyle.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,31 @@
1111
import Foundation
1212
import Markdown
1313

14+
/// A directive for specifying the style that should be used when rendering a page's
15+
/// Topics section.
1416
public class TopicsVisualStyle: Semantic, AutomaticDirectiveConvertible {
1517
public let originalMarkup: BlockDirective
1618

19+
/// The specified style that should be used when rendering a page's Topics section.
1720
@DirectiveArgumentWrapped(name: .unnamed)
1821
public private(set) var style: Style
1922

23+
/// A visual style for a page's Topics section.
2024
public enum Style: String, CaseIterable, DirectiveArgumentValueConvertible {
25+
/// A list of the page's topics, including their full declaration and abstract.
2126
case list
27+
28+
/// A grid of items based on the card image for each page.
29+
///
30+
/// Includes each page’s title and card image but excludes their abstracts.
2231
case compactGrid
32+
33+
/// A grid of items based on the card image for each page.
34+
///
35+
/// Unlike ``compactGrid``, this style includes the abstract for each page.
2336
case detailedGrid
37+
38+
/// Do not show child pages anywhere on the page.
2439
case hidden
2540
}
2641

Tests/SwiftDocCTests/Converter/RenderNodeCodableTests.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import XCTest
1212
@testable import SwiftDocC
13+
import Markdown
1314

1415
class RenderNodeCodableTests: XCTestCase {
1516

@@ -158,6 +159,70 @@ class RenderNodeCodableTests: XCTestCase {
158159
}
159160
}
160161

162+
func testDecodeRenderNodeWithoutTopicSectionStyle() throws {
163+
let exampleRenderNodeJSON = Bundle.module.url(
164+
forResource: "Operator",
165+
withExtension: "json",
166+
subdirectory: "Test Resources"
167+
)!
168+
169+
let renderNodeData = try Data(contentsOf: exampleRenderNodeJSON)
170+
171+
let renderNode = try JSONDecoder().decode(RenderNode.self, from: renderNodeData)
172+
XCTAssertEqual(renderNode.topicSectionsStyle, .list)
173+
}
174+
175+
func testEncodeRenderNodeWithCustomTopicSectionStyle() throws {
176+
let (bundle, context) = try testBundleAndContext()
177+
var problems = [Problem]()
178+
179+
let source = """
180+
# My Great Article
181+
182+
A great article.
183+
184+
@Options {
185+
@TopicsVisualStyle(compactGrid)
186+
}
187+
"""
188+
189+
let document = Document(parsing: source, options: .parseBlockDirectives)
190+
let article = try XCTUnwrap(
191+
Article(from: document.root, source: nil, for: bundle, in: context, problems: &problems)
192+
)
193+
194+
let reference = ResolvedTopicReference(
195+
bundleIdentifier: "org.swift.docc.example",
196+
path: "/documentation/test/customTopicSectionStyle",
197+
fragment: nil,
198+
sourceLanguage: .swift
199+
)
200+
context.documentationCache[reference] = try DocumentationNode(reference: reference, article: article)
201+
let topicGraphNode = TopicGraph.Node(
202+
reference: reference,
203+
kind: .article,
204+
source: .file(url: URL(fileURLWithPath: "/path/to/article.md")),
205+
title: "My Article"
206+
)
207+
context.topicGraph.addNode(topicGraphNode)
208+
209+
var translator = RenderNodeTranslator(
210+
context: context,
211+
bundle: bundle,
212+
identifier: reference,
213+
source: nil
214+
)
215+
let node = try XCTUnwrap(translator.visitArticle(article) as? RenderNode)
216+
XCTAssertEqual(node.topicSectionsStyle, .compactGrid)
217+
218+
let encoder = JSONEncoder()
219+
let decoder = JSONDecoder()
220+
221+
let encodedNode = try encoder.encode(node)
222+
let decodedNode = try decoder.decode(RenderNode.self, from: encodedNode)
223+
XCTAssertEqual(decodedNode.topicSectionsStyle, .compactGrid)
224+
}
225+
161226
private func assertVariantOverrides(_ variantOverrides: VariantOverrides) throws {
162227
XCTAssertEqual(variantOverrides.values.count, 1)
163228
let variantOverride = try XCTUnwrap(variantOverrides.values.first)

Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,32 @@ Document @1:1-11:19
17821782
"""
17831783
)
17841784
}
1785+
1786+
func testArticleRoleHeadingsWithAutomaticTitleHeadingDisabled() throws {
1787+
try assertRoleHeadingForArticleInTestBundle(expectedRoleHeading: nil, content: """
1788+
# Article 2
1789+
1790+
@Options {
1791+
@AutomaticTitleHeading(disabled)
1792+
}
1793+
1794+
This is article 2.
1795+
"""
1796+
)
1797+
}
1798+
1799+
func testArticleRoleHeadingsWithAutomaticTitleHeadingForPageKind() throws {
1800+
try assertRoleHeadingForArticleInTestBundle(expectedRoleHeading: "Article", content: """
1801+
# Article 2
1802+
1803+
@Options {
1804+
@AutomaticTitleHeading(pageKind)
1805+
}
1806+
1807+
This is article 2.
1808+
"""
1809+
)
1810+
}
17851811

17861812
func testAPICollectionRoleHeading() throws {
17871813
try assertRoleHeadingForArticleInTestBundle(expectedRoleHeading: nil, content: """

0 commit comments

Comments
 (0)