Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cf7ebc6
Add experimental markdown output flag and pass it through to the conv…
Sep 2, 2025
4b1b94a
Initial export of Markdown from Article
Sep 4, 2025
55e7836
Initial processing of a type-level symbol
Sep 4, 2025
53a6196
Adds symbol declarations and article reference links
Sep 5, 2025
3513a73
Output tutorials to markdown
Sep 5, 2025
81d2d5a
Be smarter about removing indentation from within block directives
Sep 5, 2025
f3fa5ab
Baseline for adding new tests for markdown output
Sep 8, 2025
5013a09
Basic test infrastructure for markdown output
Sep 8, 2025
6798162
Adds symbol link tests to markdown output
Sep 8, 2025
132cd6c
Tutoorial code rendering markdown tests
Sep 8, 2025
1753cca
Adding metadata to markdown output
Sep 8, 2025
301d7da
Include package source for markdown output test catalog
Sep 9, 2025
9607e3b
Output metadata updates
Sep 9, 2025
5244f0f
Adds default availability for modules to markdown export
Sep 11, 2025
a6a740e
Move availability out of symbol and in to general metadata for markdo…
Sep 16, 2025
d0dbf44
Refactor markdown output so the final node type is standalone
Sep 19, 2025
595831a
Add generated markdown flag to render node metadata
Sep 23, 2025
104f9eb
Only include unavailable in markdown header if it is true
Sep 23, 2025
a2aa8f1
Initial setup of manifest output, no references
Sep 23, 2025
b5ed559
Output of manifest / relationships
Sep 24, 2025
74b6023
Manifest output format updates
Sep 24, 2025
198d8e8
Remove member symbol relationship
Sep 25, 2025
53ba222
More compact availability, deal with metadata availability for symbols
Sep 26, 2025
af890be
Merge branch 'main' into 159600318/experimental-markdown-ouput
jrturton Sep 26, 2025
4784380
Update tests so all inputs are locally defined
Sep 29, 2025
abc9985
Remove print statements from unused visitors
Oct 2, 2025
edc74da
Merge branch 'main' into 159600318/experimental-markdown-ouput
Oct 2, 2025
eb77d39
Added snippet handling
Oct 2, 2025
0e867d7
Remove or _spi-hide new public API
Oct 2, 2025
f07f683
Remove or _spi-hide new public API (part 2)
Oct 2, 2025
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
11 changes: 11 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ let package = Package(
name: "SwiftDocC",
targets: ["SwiftDocC"]
),
.library(
name: "SwiftDocCMarkdownOutput",
targets: ["SwiftDocCMarkdownOutput"]
),
.executable(
name: "docc",
targets: ["docc"]
Expand All @@ -47,6 +51,7 @@ let package = Package(
.product(name: "SymbolKit", package: "swift-docc-symbolkit"),
.product(name: "CLMDB", package: "swift-lmdb"),
.product(name: "Crypto", package: "swift-crypto"),
.target(name: "SwiftDocCMarkdownOutput")
],
swiftSettings: swiftSettings
),
Expand Down Expand Up @@ -126,6 +131,12 @@ let package = Package(
swiftSettings: swiftSettings
),

// Experimental markdown output
.target(
name: "SwiftDocCMarkdownOutput",
dependencies: []
)

]
)

Expand Down
17 changes: 17 additions & 0 deletions Sources/SwiftDocC/Converter/DocumentationContextConverter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,21 @@ public class DocumentationContextConverter {
)
return translator.visit(node.semantic) as? RenderNode
}

/// Converts a documentation node to a markdown node.
/// - Parameters:
/// - node: The documentation node to convert.
/// - Returns: The markdown node representation of the documentation node.
internal func markdownOutput(for node: DocumentationNode) -> CollectedMarkdownOutput? {
guard !node.isVirtual else {
return nil
}

var translator = MarkdownOutputNodeTranslator(
context: context,
bundle: bundle,
node: node
)
return translator.createOutput()
}
}
24 changes: 24 additions & 0 deletions Sources/SwiftDocC/Infrastructure/ConvertActionConverter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

import Foundation
@_spi(MarkdownOutput) import SwiftDocCMarkdownOutput

#if canImport(os)
package import os
Expand Down Expand Up @@ -81,6 +82,7 @@ package enum ConvertActionConverter {
var assets = [RenderReferenceType : [any RenderReference]]()
var coverageInfo = [CoverageDataEntry]()
let coverageFilterClosure = documentationCoverageOptions.generateFilterClosure()
var markdownManifest = MarkdownOutputManifest(title: bundle.displayName, documents: [])

// An inner function to gather problems for errors encountered during the conversion.
//
Expand Down Expand Up @@ -129,6 +131,22 @@ package enum ConvertActionConverter {
return
}

if
FeatureFlags.current.isExperimentalMarkdownOutputEnabled,
let markdownConsumer = outputConsumer as? (any ConvertOutputMarkdownConsumer),
let markdownNode = converter.markdownOutput(for: entity) {
try markdownConsumer.consume(markdownNode: markdownNode.writable)
if
FeatureFlags.current.isExperimentalMarkdownOutputManifestEnabled,
let manifest = markdownNode.manifest
{
resultsGroup.async(queue: resultsSyncQueue) {
markdownManifest.documents.formUnion(manifest.documents)
markdownManifest.relationships.formUnion(manifest.relationships)
}
}
}

try outputConsumer.consume(renderNode: renderNode)

switch documentationCoverageOptions.level {
Expand Down Expand Up @@ -213,6 +231,12 @@ package enum ConvertActionConverter {
}
}
}

if
FeatureFlags.current.isExperimentalMarkdownOutputManifestEnabled,
let markdownConsumer = outputConsumer as? (any ConvertOutputMarkdownConsumer) {
try markdownConsumer.consume(markdownManifest: try markdownManifest.writable)
}

switch documentationCoverageOptions.level {
case .detailed, .brief:
Expand Down
13 changes: 12 additions & 1 deletion Sources/SwiftDocC/Infrastructure/ConvertOutputConsumer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

import Foundation

@_spi(MarkdownOutput) import SwiftDocCMarkdownOutput
/// A consumer for output produced by a documentation conversion.
///
/// Types that conform to this protocol manage what to do with documentation conversion products, for example persist them to disk
Expand Down Expand Up @@ -50,6 +50,17 @@ public protocol ConvertOutputConsumer {

/// Consumes a file representation of the local link resolution information.
func consume(linkResolutionInformation: SerializableLinkResolutionInformation) throws

}

// Merge into ConvertOutputMarkdownConsumer when no longer SPI
@_spi(MarkdownOutput)
public protocol ConvertOutputMarkdownConsumer {
/// Consumes a markdown output node
func consume(markdownNode: WritableMarkdownOutputNode) throws

/// Consumes a markdown output manifest
func consume(markdownManifest: WritableMarkdownOutputManifest) throws
}

// Default implementations that discard the documentation conversion products, for consumers that don't need these
Expand Down
Loading