Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Sources/DocCHTML/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_library(DocCHTML STATIC
MarkdownRenderer+Availability.swift
MarkdownRenderer+Breadcrumbs.swift
MarkdownRenderer+Parameters.swift
MarkdownRenderer+Returns.swift
MarkdownRenderer.swift
WordBreak.swift
XMLNode+element.swift)
Expand Down
4 changes: 2 additions & 2 deletions Sources/DocCHTML/MarkdownRenderer+Parameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ package extension MarkdownRenderer {

/// Creates a "parameters" section that describes all the parameters for a symbol.
///
/// If each language representation of the API has their own language-specific parameters, pass each language representation's parameter information.
/// If each language representation of the symbol have their own language-specific parameters, pass the parameter information for all language representations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// If each language representation of the symbol have their own language-specific parameters, pass the parameter information for all language representations.
/// If each language representation of the symbol has its own language-specific parameters, pass the parameter information for all language representations.

///
/// If the API has the _same_ parameters in all language representations, only pass the parameters for one language.
/// If all language representations of the symbol have the _same_ parameters, only pass the parameter information for one language.
/// This produces a "parameters" section that doesn't hide any parameters for any of the languages (same as if the symbol only had one language representation)
func parameters(_ info: [SourceLanguage: [ParameterInfo]]) -> [XMLNode] {
let info = RenderHelpers.sortedLanguageSpecificValues(info)
Expand Down
52 changes: 52 additions & 0 deletions Sources/DocCHTML/MarkdownRenderer+Returns.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
This source file is part of the Swift.org open source project

Copyright (c) 2025 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if canImport(FoundationXML)
// TODO: Consider other HTML rendering options as a future improvement (rdar://165755530)
package import FoundationXML
#else
package import Foundation
#endif

package import Markdown
package import DocCCommon

package extension MarkdownRenderer {
/// Creates a "returns" section that describes all return values of a symbol.
///
/// If each language representation of the symbol have their own language-specific return values, pass the return value content for all language representations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// If each language representation of the symbol have their own language-specific return values, pass the return value content for all language representations.
/// If each language representation of the symbol has its own language-specific return values, pass the return value content for all language representations.

///
/// If all language representations of the symbol have the _same_ return value, only pass the return value content for one language.
/// This produces a "returns" section that doesn't hide the return value content for any of the languages (same as if the symbol only had one language representation)
func returns(_ languageSpecificSections: [SourceLanguage: [any Markup]]) -> [XMLNode] {
let info = RenderHelpers.sortedLanguageSpecificValues(languageSpecificSections)
let items: [XMLNode] = if info.count == 1 {
info.first!.value.map { visit($0) }
} else {
info.flatMap { language, content in
let attributes = ["class": "\(language.id)-only"]
// Most return sections only have 1 paragraph of content with 2 and 3 paragraphs being increasingly uncommon.
// Avoid wrapping that content in a `<div>` or other container element and instead add the language specific class attribute to each paragraph.
return content.map { markup in
let node = visit(markup)
if let element = node as? XMLElement {
element.addAttributes(attributes)
return element
} else {
// Any text _should_ already be contained in a markdown paragraph, but if the input is unexpected, wrap the raw text in a paragraph here.
return .element(named: "p", children: [node], attributes: attributes)
}
}
}
}

return selfReferencingSection(named: "Return Value", content: items)
}
}
60 changes: 60 additions & 0 deletions Tests/DocCHTMLTests/MarkdownRenderer+PageElementsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,66 @@ struct MarkdownRenderer_PageElementsTests {
""")
}

@Test(arguments: RenderGoal.allCases)
func testRenderSingleLanguageReturnSections(goal: RenderGoal) {
let returns = makeRenderer(goal: goal).returns([
.swift: parseMarkup(string: "First paragraph\n\nSecond paragraph")
])

let commonHTML = """
<p>First paragraph</p>
<p>Second paragraph</p>
"""

switch goal {
case .richness:
returns.assertMatches(prettyFormatted: true, expectedXMLString: """
<section id="Return-Value">
<h2>
<a href="#Return-Value">Return Value</a>
</h2>
\(commonHTML)
</section>
""")
case .conciseness:
returns.assertMatches(prettyFormatted: true, expectedXMLString: """
<h2>Return Value</h2>
\(commonHTML)
""")
}
}

@Test(arguments: RenderGoal.allCases)
func testRenderLanguageSpecificReturnSections(goal: RenderGoal) {
let returns = makeRenderer(goal: goal).returns([
.swift: parseMarkup(string: "First paragraph\n\nSecond paragraph"),
.objectiveC: parseMarkup(string: "Other language's paragraph"),
])

let commonHTML = """
<p class="swift-only">First paragraph</p>
<p class="swift-only">Second paragraph</p>
<p class="occ-only">Other language’s paragraph</p>
"""

switch goal {
case .richness:
returns.assertMatches(prettyFormatted: true, expectedXMLString: """
<section id="Return-Value">
<h2>
<a href="#Return-Value">Return Value</a>
</h2>
\(commonHTML)
</section>
""")
case .conciseness:
returns.assertMatches(prettyFormatted: true, expectedXMLString: """
<h2>Return Value</h2>
\(commonHTML)
""")
}
}

// MARK: -

private func makeRenderer(
Expand Down