Skip to content

Commit 983a415

Browse files
committed
Add a new target for rendering content into static HTML
rdar://163326857
1 parent b2975d8 commit 983a415

File tree

8 files changed

+1702
-1
lines changed

8 files changed

+1702
-1
lines changed

Package.swift

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

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

88
See https://swift.org/LICENSE.txt for license information
@@ -122,6 +122,7 @@ let package = Package(
122122
// This target shouldn't have any local dependencies so that all other targets can depend on it.
123123
// We can add dependencies on SymbolKit and Markdown here but they're not needed yet.
124124
],
125+
exclude: ["CMakeLists.txt"],
125126
swiftSettings: [.swiftLanguageMode(.v6)]
126127
),
127128

@@ -134,6 +135,27 @@ let package = Package(
134135
swiftSettings: [.swiftLanguageMode(.v6)]
135136
),
136137

138+
.target(
139+
name: "DocCHTML",
140+
dependencies: [
141+
.target(name: "DocCCommon"),
142+
.product(name: "Markdown", package: "swift-markdown"),
143+
.product(name: "SymbolKit", package: "swift-docc-symbolkit"),
144+
],
145+
exclude: ["CMakeLists.txt"],
146+
swiftSettings: [.swiftLanguageMode(.v6)]
147+
),
148+
.testTarget(
149+
name: "DocCHTMLTests",
150+
dependencies: [
151+
.target(name: "DocCHTML"),
152+
.target(name: "SwiftDocC"),
153+
.product(name: "Markdown", package: "swift-markdown"),
154+
.target(name: "SwiftDocCTestUtilities"),
155+
],
156+
swiftSettings: [.swiftLanguageMode(.v6)]
157+
),
158+
137159
// Test app for SwiftDocCUtilities
138160
.executableTarget(
139161
name: "signal-test-app",

Sources/DocCHTML/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#[[
2+
This source file is part of the Swift open source project
3+
4+
Copyright © 2014 - 2025 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
#]]
9+
10+
add_library(DocCHTML STATIC
11+
LinkProvider.swift
12+
MarkdownRenderer.swift
13+
WordBreak.swift
14+
XMLNode+element.swift)
15+
target_link_libraries(DocCHTML PRIVATE
16+
DocCCommon)
17+
target_link_libraries(DocCHTML PUBLIC
18+
SwiftMarkdown::Markdown
19+
DocC::SymbolKit)
20+
# FIXME(compnerd) workaround leaking dependencies
21+
target_link_libraries(DocCHTML PUBLIC
22+
libcmark-gfm
23+
libcmark-gfm-extensions)
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2025 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
package import Foundation
12+
package import Markdown
13+
package import DocCCommon
14+
15+
/// A type that provides information about other pages, and on-page elements, that the rendered page references.
16+
package protocol LinkProvider {
17+
/// Provide information about another page or on-page element, or `nil` if the other page can't be found.
18+
func element(for path: URL) -> LinkedElement?
19+
20+
/// Provide the path for a symbol based on its unique identifier, or `nil` if the other symbol with that identifier can't be found.
21+
func pathForSymbolID(_ usr: String) -> URL?
22+
23+
/// Provide information about an asset, or `nil` if the asset can't be found.
24+
func assetNamed(_ assetName: String) -> LinkedAsset?
25+
26+
/// Fallback link text for a link string that the provider couldn't provide any information for.
27+
func fallbackLinkText(linkString: String) -> String
28+
}
29+
30+
package struct LinkedElement {
31+
/// The path within the output archive to the linked element.
32+
package var path: URL
33+
/// The names of the linked element, for display when the element is referenced in inline content.
34+
///
35+
/// Articles, headings, tutorials, and similar pages have a ``Names/single/conceptual(_:)`` name.
36+
/// Symbols can either have a ``Names/single/symbol(_:)`` name or have different names for each language representation (``Names/languageSpecificSymbol``).
37+
package var names: Names
38+
/// The subheadings of the linked element, for display when the element is referenced in either a Topics section, See Also section, or in a `@Links` directive.
39+
///
40+
/// Articles, headings, tutorials, and similar pages have a ``Names/single/conceptual(_:)`` name.
41+
/// Symbols can either have a ``Names/single/symbol(_:)`` name or have different names for each language representation (``Names/languageSpecificSymbol``).
42+
package var subheadings: Subheadings
43+
/// The abstract of the page—to be displayed in either a Topics section, See Also section, or in a `@Links` directive—or `nil` if the linked element doesn't have an abstract.
44+
package var abstract: Paragraph?
45+
46+
package init(path: URL, names: Names, subheadings: Subheadings, abstract: Paragraph?) {
47+
self.path = path
48+
self.names = names
49+
self.subheadings = subheadings
50+
self.abstract = abstract
51+
}
52+
53+
/// The single name or language-specific names to use when referring to a linked element in inline content.
54+
package enum Names {
55+
/// This element has the same name in all language representations
56+
case single(Name)
57+
/// This element is a symbol with different names in different languages.
58+
///
59+
/// Because `@DisplayName` applies to all language representations, these language specific names are always the symbol's subheading declaration and should display in a monospaced font.
60+
case languageSpecificSymbol([SourceLanguage: String])
61+
}
62+
package enum Name {
63+
/// The name refers to an article, heading, or custom `@DisplayName` and should display as regular text.
64+
case conceptual(String)
65+
/// The name refers to a symbol's subheading declaration and should display in a monospaced font.
66+
case symbol(String)
67+
}
68+
69+
/// The single subheading or language-specific subheadings to use when referring to a linked element in either a Topics section, See Also section, or in a `@Links` directive.
70+
package enum Subheadings {
71+
/// This element has the same name in all language representations
72+
case single(Subheading)
73+
/// This element is a symbol with different names in different languages.
74+
///
75+
/// Because `@DisplayName` applies to all language representations, these language specific names are always the symbol's subheading declaration and should display in a monospaced font.
76+
case languageSpecificSymbol([SourceLanguage: [SymbolNameFragment]])
77+
}
78+
package enum Subheading {
79+
/// The name refers to an article, heading, or custom `@DisplayName` and should display as regular text.
80+
case conceptual(String)
81+
/// The name refers to a symbol's subheading declaration and should display in a monospaced font.
82+
case symbol([SymbolNameFragment])
83+
}
84+
85+
/// A fragment in a symbol's name
86+
package struct SymbolNameFragment {
87+
/// The textual spelling of this fragment
88+
package var text: String
89+
/// The kind of fragment
90+
package var kind: Kind
91+
92+
/// The display kind of a single symbol name fragment
93+
package enum Kind: String {
94+
case identifier, decorator
95+
}
96+
97+
package init(text: String, kind: Kind) {
98+
self.text = text
99+
self.kind = kind
100+
}
101+
}
102+
}
103+
104+
package struct LinkedAsset {
105+
/// The path within the output archive to each image variant, by their light/dark style.
106+
package var images: [ColorStyle: [Int /* display scale*/: URL]]
107+
108+
package init(images: [ColorStyle : [Int : URL]]) {
109+
self.images = images
110+
}
111+
112+
package enum ColorStyle: String {
113+
case light, dark
114+
}
115+
}

0 commit comments

Comments
 (0)