Skip to content

Commit 1f4894d

Browse files
author
Jesse Haigh
committed
copy by default
1 parent bb50fb9 commit 1f4894d

File tree

8 files changed

+49
-25
lines changed

8 files changed

+49
-25
lines changed

Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public enum RenderBlockContent: Equatable {
124124
public var code: [String]
125125
/// Additional metadata for this code block.
126126
public var metadata: RenderContentMetadata?
127-
public var copyToClipboard: Bool = false
127+
public var copyToClipboard: Bool = true
128128

129129
/// Make a new `CodeListing` with the given data.
130130
public init(syntax: String?, code: [String], metadata: RenderContentMetadata?, copyToClipboard: Bool) {
@@ -725,7 +725,7 @@ extension RenderBlockContent: Codable {
725725
syntax: container.decodeIfPresent(String.self, forKey: .syntax),
726726
code: container.decode([String].self, forKey: .code),
727727
metadata: container.decodeIfPresent(RenderContentMetadata.self, forKey: .metadata),
728-
copyToClipboard: container.decodeIfPresent(Bool.self, forKey: .copyToClipboard) ?? false
728+
copyToClipboard: container.decodeIfPresent(Bool.self, forKey: .copyToClipboard) ?? true
729729
))
730730
case .heading:
731731
self = try .heading(.init(level: container.decode(Int.self, forKey: .level), text: container.decode(String.self, forKey: .text), anchor: container.decodeIfPresent(String.self, forKey: .anchor)))

Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct RenderContentCompiler: MarkupVisitor {
4949
// Default to the bundle's code listing syntax if one is not explicitly declared in the code block.
5050
struct ParsedOptions {
5151
var lang: String?
52-
var copy = false
52+
var nocopy = false
5353
}
5454

5555
func parseLanguageString(_ input: String?) -> ParsedOptions {
@@ -63,8 +63,8 @@ struct RenderContentCompiler: MarkupVisitor {
6363

6464
for part in parts {
6565
let lower = part.lowercased()
66-
if lower == "copy" {
67-
options.copy = true
66+
if lower == "nocopy" {
67+
options.nocopy = true
6868
} else if options.lang == nil {
6969
options.lang = part
7070
}
@@ -74,7 +74,7 @@ struct RenderContentCompiler: MarkupVisitor {
7474

7575
let options = parseLanguageString(codeBlock.language)
7676

77-
return [RenderBlockContent.codeListing(.init(syntax: options.lang ?? bundle.info.defaultCodeListingLanguage, code: codeBlock.code.splitByNewlines, metadata: nil, copyToClipboard: options.copy))]
77+
return [RenderBlockContent.codeListing(.init(syntax: options.lang ?? bundle.info.defaultCodeListingLanguage, code: codeBlock.code.splitByNewlines, metadata: nil, copyToClipboard: !options.nocopy))]
7878
}
7979

8080
mutating func visitHeading(_ heading: Heading) -> [any RenderContent] {

Sources/SwiftDocC/Semantics/Snippets/Snippet.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,11 @@ extension Snippet: RenderableDirectiveConvertible {
6868
let lines = snippetMixin.lines[lineRange]
6969
let minimumIndentation = lines.map { $0.prefix { $0.isWhitespace }.count }.min() ?? 0
7070
let trimmedLines = lines.map { String($0.dropFirst(minimumIndentation)) }
71-
let copy = true
72-
return [RenderBlockContent.codeListing(.init(syntax: snippetMixin.language, code: trimmedLines, metadata: nil, copyToClipboard: copy))]
71+
return [RenderBlockContent.codeListing(.init(syntax: snippetMixin.language, code: trimmedLines, metadata: nil, copyToClipboard: true))]
7372
} else {
7473
// Render the whole snippet with its explanation content.
7574
let docCommentContent = snippetEntity.markup.children.flatMap { contentCompiler.visit($0) }
76-
let code = RenderBlockContent.codeListing(.init(syntax: snippetMixin.language, code: snippetMixin.lines, metadata: nil, copyToClipboard: false))
75+
let code = RenderBlockContent.codeListing(.init(syntax: snippetMixin.language, code: snippetMixin.lines, metadata: nil, copyToClipboard: true))
7776
return docCommentContent + [code]
7877
}
7978
}

Sources/docc/DocCDocumentation.docc/formatting-your-documentation-content.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,17 @@ documentation.
145145

146146
#### Formatting Code Listings
147147

148-
You can add a copy-to-clipboard button to a code listing by including the copy
149-
option after the name of the programming language for the code listing:
148+
A copy-to-clipboard button is added to code listings by default behind the
149+
feature flag `--enable-experimental-code-block`.
150+
This renders a copy button in the top-right cotner of the code listing in
151+
generated documentation. When clicked, it copies the contents of the code
152+
block to the clipboard.
153+
154+
If you don't want a code block to have a copy-to-clipboard button, you can
155+
include the `nocopy` option after the name of the programming language to
156+
disable it for that code listing:
150157

151-
```swift, copy
158+
```swift, nocopy
152159
struct Sightseeing: Activity {
153160
func perform(with sloth: inout Sloth) -> Speed {
154161
sloth.energyLevel -= 10
@@ -157,10 +164,6 @@ struct Sightseeing: Activity {
157164
}
158165
```
159166

160-
This renders a copy button in the top-right cotner of the code listing in
161-
generated documentation. When clicked, it copies the contents of the code
162-
block to the clipboard.
163-
164167
DocC uses the programming language you specify to apply the correct syntax
165168
color formatting. For the example above, DocC generates the following:
166169

Tests/SwiftDocCTests/Model/RenderContentMetadataTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class RenderContentMetadataTests: XCTestCase {
5454
RenderInlineContent.text("Content"),
5555
])
5656

57-
let code = RenderBlockContent.codeListing(.init(syntax: nil, code: [], metadata: metadata, copyToClipboard: false))
57+
let code = RenderBlockContent.codeListing(.init(syntax: nil, code: [], metadata: metadata, copyToClipboard: true))
5858
let data = try JSONEncoder().encode(code)
5959
let roundtrip = try JSONDecoder().decode(RenderBlockContent.self, from: data)
6060

Tests/SwiftDocCTests/Model/RenderNodeSerializationTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class RenderNodeSerializationTests: XCTestCase {
4444
.strong(inlineContent: [.text("Project > Run")]),
4545
.text(" menu item, or the following code:"),
4646
])),
47-
.codeListing(.init(syntax: "swift", code: ["xcrun xcodebuild -h", "xcrun xcodebuild build -configuration Debug"], metadata: nil, copyToClipboard: false)),
47+
.codeListing(.init(syntax: "swift", code: ["xcrun xcodebuild -h", "xcrun xcodebuild build -configuration Debug"], metadata: nil, copyToClipboard: true)),
4848
]))
4949
]
5050

@@ -71,16 +71,16 @@ class RenderNodeSerializationTests: XCTestCase {
7171
let assessment1 = TutorialAssessmentsRenderSection.Assessment(title: [.paragraph(.init(inlineContent: [.text("Lorem ipsum dolor sit amet?")]))],
7272
content: nil,
7373
choices: [
74-
.init(content: [.codeListing(.init(syntax: "swift", code: ["override func viewDidLoad() {", "super.viewDidLoad()", "}"], metadata: nil, copyToClipboard: false))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "That's right!"),
75-
.init(content: [.codeListing(.init(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil, copyToClipboard: false))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: "Not quite."),
74+
.init(content: [.codeListing(.init(syntax: "swift", code: ["override func viewDidLoad() {", "super.viewDidLoad()", "}"], metadata: nil, copyToClipboard: true))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "That's right!"),
75+
.init(content: [.codeListing(.init(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil, copyToClipboard: true))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: "Not quite."),
7676
.init(content: [.paragraph(.init(inlineContent: [.text("None of the above.")]))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: nil),
7777
])
7878

7979
let assessment2 = TutorialAssessmentsRenderSection.Assessment(title: [.paragraph(.init(inlineContent: [.text("Duis aute irure dolor in reprehenderit?")]))],
8080
content: [.paragraph(.init(inlineContent: [.text("What is the airspeed velocity of an unladen swallow?")]))],
8181
choices: [
82-
.init(content: [.codeListing(.init(syntax: "swift", code: ["super.viewWillAppear()"], metadata: nil, copyToClipboard: false))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "Correct."),
83-
.init(content: [.codeListing(.init(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil, copyToClipboard: false))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "Yep."),
82+
.init(content: [.codeListing(.init(syntax: "swift", code: ["super.viewWillAppear()"], metadata: nil, copyToClipboard: true))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "Correct."),
83+
.init(content: [.codeListing(.init(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil, copyToClipboard: true))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "Yep."),
8484
.init(content: [.paragraph(.init(inlineContent: [.text("None of the above.")]))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: "Close!"),
8585
])
8686

Tests/SwiftDocCTests/Rendering/RenderContentCompilerTests.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ class RenderContentCompilerTests: XCTestCase {
229229
var compiler = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleID: bundle.id, path: "/path", fragment: nil, sourceLanguage: .swift))
230230

231231
let source = #"""
232-
```swift, copy
232+
```swift
233233
let x = 1
234234
```
235235
"""#
@@ -245,4 +245,26 @@ class RenderContentCompilerTests: XCTestCase {
245245

246246
XCTAssertEqual(codeListing.copyToClipboard, true)
247247
}
248+
249+
func testNoCopyToClipboard() async throws {
250+
let (bundle, context) = try await testBundleAndContext()
251+
var compiler = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleID: bundle.id, path: "/path", fragment: nil, sourceLanguage: .swift))
252+
253+
let source = #"""
254+
```swift, nocopy
255+
let x = 1
256+
```
257+
"""#
258+
let document = Document(parsing: source)
259+
260+
let result = document.children.flatMap { compiler.visit($0) }
261+
262+
let renderCodeBlock = try XCTUnwrap(result[0] as? RenderBlockContent)
263+
guard case let .codeListing(codeListing) = renderCodeBlock else {
264+
XCTFail("Expected RenderBlockContent.codeListing")
265+
return
266+
}
267+
268+
XCTAssertEqual(codeListing.copyToClipboard, false)
269+
}
248270
}

Tests/SwiftDocCTests/Utility/ListItemExtractorTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,8 @@ class ListItemExtractorTests: XCTestCase {
514514
// ```
515515
// Inner code block
516516
// ```
517-
.codeListing(.init(syntax: nil, code: ["Inner code block"], metadata: nil, copyToClipboard: false)),
518-
517+
.codeListing(.init(syntax: nil, code: ["Inner code block"], metadata: nil, copyToClipboard: true)),
518+
519519
// > Warning: Inner aside, with ``ThirdNotFoundSymbol`` link
520520
.aside(.init(style: .init(asideKind: .warning), content: [
521521
.paragraph(.init(inlineContent: [

0 commit comments

Comments
 (0)