diff --git a/Sources/DocCHTML/CMakeLists.txt b/Sources/DocCHTML/CMakeLists.txt index 4bf8da392..531ccff0b 100644 --- a/Sources/DocCHTML/CMakeLists.txt +++ b/Sources/DocCHTML/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(DocCHTML STATIC LinkProvider.swift MarkdownRenderer+Availability.swift MarkdownRenderer+Breadcrumbs.swift + MarkdownRenderer+Parameters.swift MarkdownRenderer.swift WordBreak.swift XMLNode+element.swift) diff --git a/Sources/DocCHTML/MarkdownRenderer+Parameters.swift b/Sources/DocCHTML/MarkdownRenderer+Parameters.swift new file mode 100644 index 000000000..46e2ac32b --- /dev/null +++ b/Sources/DocCHTML/MarkdownRenderer+Parameters.swift @@ -0,0 +1,144 @@ +/* + 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 { + /// Information about a specific parameter for a piece of API. + struct ParameterInfo { + /// The name of the parameter. + package var name: String + /// The markdown content that describes the parameter. + package var content: [any Markup] + + package init(name: String, content: [any Markup]) { + self.name = name + self.content = content + } + } + + /// 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 the API has the _same_ parameters in all language representations, only pass the parameters 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) + guard info.contains(where: { _, parameters in !parameters.isEmpty }) else { + // Don't create a section if there are no parameters to describe. + return [] + } + + let items: [XMLElement] = switch info.count { + case 1: + [_singleLanguageParameters(info.first!.value)] + + case 2: + [_dualLanguageParameters(primary: info.first!, secondary: info.last!)] + + default: + // In practice DocC only encounters one or two different languages. If there would be a third one, + // produce correct looking pages that may include duplicated markup by not trying to share parameters across languages. + info.map { language, info in + .element( + named: "dl", + children: _singleLanguageParameterItems(info), + attributes: ["class": "\(language.id)-only"] + ) + } + } + + return selfReferencingSection(named: "Parameters", content: items) + } + + private func _singleLanguageParameters(_ parameterInfo: [ParameterInfo]) -> XMLElement { + .element(named: "dl", children: _singleLanguageParameterItems(parameterInfo)) + } + + private func _singleLanguageParameterItems(_ parameterInfo: [ParameterInfo]) -> [XMLElement] { + // When there's only a single language representation, create a list of `
First
+
+ Some formatted description with code
+
Second
+ + Some other formatted description
+That spans two paragraphs
+First
+ Some formatteddescription with code
+
Second
+ + Some other formatted description
+That spans two paragraphs
+FirstCommon
+ Available in both languages
+SwiftOnly
+ Only available in Swift
+SecondCommon
+ Also available in both languages
+ObjectiveCOnly
+ Only available in Objective-C
+First
+ Some description
+Third
+ Some description
+Second
+ Some description
+