Skip to content

Commit c0daf6e

Browse files
authored
Add title bar for code blocks in the Demo app CodeSyntaxHighlightView (#249)
1 parent 723249a commit c0daf6e

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

Examples/Demo/Demo/CodeSyntaxHighlightView.swift

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct CodeSyntaxHighlightView: View {
2626
}
2727
2828
func highlightCode(_ content: String, language: String?) -> Text {
29-
guard language?.lowercased() == "swift" else {
29+
guard language != nil else {
3030
return Text(content)
3131
}
3232
@@ -50,15 +50,92 @@ struct CodeSyntaxHighlightView: View {
5050
.markdownCodeSyntaxHighlighter(.splash(theme: .sunset(withFont: .init(size: 16))))
5151
}
5252
```
53+
54+
More languages to render:
55+
56+
```
57+
A plain code block without the specifying a language name.
58+
```
59+
60+
```cpp
61+
#include <iostream>
62+
#include <vector>
63+
64+
int main() {
65+
std::vector<std::string> fruits = {"apple", "banana", "orange"};
66+
for (const std::string& fruit : fruits) {
67+
std::cout << "I love " << fruit << "s!" << std::endl;
68+
}
69+
return 0;
70+
}
71+
```
72+
73+
```typescript
74+
interface Person {
75+
name: string;
76+
age: number;
77+
}
78+
79+
const person = Person();
80+
```
81+
82+
```ruby
83+
fruits = ["apple", "banana", "orange"]
84+
fruits.each do |fruit|
85+
puts "I love #{fruit}s!"
86+
end
87+
```
88+
5389
"""#
5490

5591
var body: some View {
5692
DemoView {
5793
Markdown(self.content)
94+
.markdownBlockStyle(\.codeBlock) {
95+
codeBlock($0)
96+
}
5897
.markdownCodeSyntaxHighlighter(.splash(theme: self.theme))
5998
}
6099
}
61100

101+
@ViewBuilder
102+
private func codeBlock(_ configuration: CodeBlockConfiguration) -> some View {
103+
VStack(spacing: 0) {
104+
HStack {
105+
Text(configuration.language ?? "plain text")
106+
.font(.system(.caption, design: .monospaced))
107+
.fontWeight(.semibold)
108+
.foregroundColor(Color(theme.plainTextColor))
109+
Spacer()
110+
111+
Image(systemName: "clipboard")
112+
.onTapGesture {
113+
copyToClipboard(configuration.content)
114+
}
115+
}
116+
.padding(.horizontal)
117+
.padding(.vertical, 8)
118+
.background {
119+
Color(theme.backgroundColor)
120+
}
121+
122+
Divider()
123+
124+
ScrollView(.horizontal) {
125+
configuration.label
126+
.relativeLineSpacing(.em(0.25))
127+
.markdownTextStyle {
128+
FontFamilyVariant(.monospaced)
129+
FontSize(.em(0.85))
130+
}
131+
.padding()
132+
}
133+
}
134+
.background(Color(.secondarySystemBackground))
135+
.clipShape(RoundedRectangle(cornerRadius: 8))
136+
.markdownMargin(top: .zero, bottom: .em(0.8))
137+
}
138+
62139
private var theme: Splash.Theme {
63140
// NOTE: We are ignoring the Splash theme font
64141
switch self.colorScheme {
@@ -68,6 +145,17 @@ struct CodeSyntaxHighlightView: View {
68145
return .sunset(withFont: .init(size: 16))
69146
}
70147
}
148+
149+
private func copyToClipboard(_ string: String) {
150+
#if os(macOS)
151+
if let pasteboard = NSPasteboard.general {
152+
pasteboard.clearContents()
153+
pasteboard.setString(string, forType: .string)
154+
}
155+
#elseif os(iOS)
156+
UIPasteboard.general.string = string
157+
#endif
158+
}
71159
}
72160

73161
struct CodeSyntaxHighlightView_Previews: PreviewProvider {

Examples/Demo/Demo/SyntaxHighlighter/SplashCodeSyntaxHighlighter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct SplashCodeSyntaxHighlighter: CodeSyntaxHighlighter {
1010
}
1111

1212
func highlightCode(_ content: String, language: String?) -> Text {
13-
guard language?.lowercased() == "swift" else {
13+
guard language != nil else {
1414
return Text(content)
1515
}
1616

0 commit comments

Comments
 (0)