Skip to content

Commit 30c6c10

Browse files
committed
feat: add markdown as a language (plaintext too)
1 parent f7e1ea1 commit 30c6c10

File tree

6 files changed

+55
-60
lines changed

6 files changed

+55
-60
lines changed

Sources/App/SiteMiddleware.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,10 @@ private extension Metadata {
9999
}
100100

101101
extension CodeLang {
102-
fileprivate static func resolve(_ req: Request) -> CodeLang? {
102+
fileprivate static func resolve(_ req: Request) -> CodeLang {
103103
req.uri.queryParameters["codeLang"]
104-
.flatMap {
105-
$0 == "markdown" || $0 == "md"
106-
? nil
107-
: CodeLang(rawValue: $0.trimmingCharacters(in: .whitespacesAndNewlines).lowercased())
108-
}
104+
.flatMap {
105+
CodeLang(rawValue: $0.trimmingCharacters(in: .whitespacesAndNewlines).lowercased())
106+
} ?? .markdown
109107
}
110108
}

Sources/Pages/Components/HeaderView.swift

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import HTML
44
import Vue
55

66
struct HeaderView: HTML {
7-
let selected: Vue.Expression<CodeLang?>
7+
let selected: Vue.Expression<CodeLang>
88

99
var body: some HTML {
1010
header {
@@ -30,14 +30,16 @@ struct HeaderView: HTML {
3030
}
3131
}
3232

33+
@Vue.Component
3334
private struct CodeSelector: HTML {
34-
let selected: Vue.Expression<CodeLang?>
35+
let selected: Vue.Expression<CodeLang>
36+
@Vue.Reactive let visible = false
3537

3638
var body: some HTML {
37-
#VueScope(false) { visible in
39+
div {
3840
button(
39-
.v.on(.click, visible.assign(!visible)),
40-
.v.bind(attrOrProp: "aria-pressed", visible)
41+
.v.on(.click, $visible.assign(!$visible)),
42+
.v.bind(attrOrProp: "aria-pressed", $visible)
4143
) {
4244
code { "</>" }
4345
}
@@ -51,23 +53,19 @@ private struct CodeSelector: HTML {
5153
.inlineStyle("background", "#8A8A8A", post: "[aria-pressed=\"true\"]")
5254
.inlineStyle("color", "#080808", post: "[aria-pressed=\"true\"]")
5355

54-
ul(.hidden, .v.bind(attrOrProp: "hidden", !visible)) {
55-
for codeLang in [nil] + CodeLang.allCases {
56+
ul(.hidden, .v.bind(attrOrProp: "hidden", !$visible)) {
57+
for codeLang in CodeLang.allCases {
5658
li {
5759
button(
5860
.v.on(
5961
.click,
60-
Expression(
61-
rawValue: "\(selected.assign(Expression(codeLang))), \(visible.assign(!visible))"
62-
)
62+
Expression(rawValue: "\(selected.assign(Expression(codeLang))), \($visible.assign(!$visible))")
6363
),
6464
.v.bind(attrOrProp: "aria-selected", selected == Expression(codeLang))
6565
) {
66-
p {
67-
codeLang?.title ?? "Markdown"
68-
}
69-
.inlineStyle("width", "100%")
70-
.inlineStyle("padding", "0.5rem")
66+
p { codeLang.title }
67+
.inlineStyle("width", "100%")
68+
.inlineStyle("padding", "0.5rem")
7169
}
7270
.inlineStyle("all", "unset")
7371
.inlineStyle("display", "block")

Sources/Pages/Components/SectionView.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import Vue
55

66
struct SectionView<Header: HTML, Content: HTML>: HTML {
77
let id: String
8-
let selected: Vue.Expression<CodeLang?>
9-
@HTMLBuilder let header: @Sendable (CodeLang?) -> Header
8+
let selected: Vue.Expression<CodeLang>
9+
@HTMLBuilder let header: @Sendable (CodeLang) -> Header
1010
@HTMLBuilder let content: @Sendable () -> Content
1111

1212
var body: some HTML {
@@ -30,7 +30,7 @@ struct SectionView<Header: HTML, Content: HTML>: HTML {
3030
.inlineStyle("padding-bottom", "0.5rem")
3131

3232
CodeLang.conditionalCases(initial: selected) { lang in
33-
if let lang {
33+
if lang != .markdown {
3434
pre {
3535
code(.class("hljs language-\(lang.rawValue)")) {
3636
self.header(lang)
@@ -39,7 +39,7 @@ struct SectionView<Header: HTML, Content: HTML>: HTML {
3939
.inlineStyle("white-space", "pre-wrap")
4040
} else {
4141
hgroup {
42-
self.header(nil)
42+
self.header(.markdown)
4343
}
4444
}
4545
}
@@ -57,10 +57,10 @@ struct SectionView<Header: HTML, Content: HTML>: HTML {
5757
}
5858

5959
extension CodeLang {
60-
static func slugToFileName(_ slug: String, lang: CodeLang?) -> String {
60+
static func slugToFileName(_ slug: String, lang: CodeLang) -> String {
6161
let fileName =
6262
switch lang {
63-
case .none: slug
63+
case .markdown: slug
6464
case .swift:
6565
slug.components(separatedBy: "-")
6666
.map { component -> String in
@@ -86,7 +86,7 @@ extension CodeLang {
8686
}
8787
.joined()
8888
}
89-
return fileName + "." + (lang?.ext ?? "md")
89+
return fileName + "." + lang.ext
9090
}
9191
}
9292

Sources/Pages/HomePage.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import Vue
99
public struct HomePage: Page, Sendable {
1010
public let title = "Portfolio | Erik Bautista Santibanez"
1111

12-
@Vue.Reactive let codeLang: CodeLang?
12+
@Vue.Reactive let codeLang: CodeLang
1313

14-
public init(codeLang: CodeLang? = .swift) {
14+
public init(codeLang: CodeLang) {
1515
self.codeLang = codeLang
1616
}
1717

@@ -34,7 +34,7 @@ public struct HomePage: Page, Sendable {
3434
private struct UserView: HTML {
3535
@Dependency(\.activityClient) private var activityClient
3636

37-
let selected: Vue.Expression<CodeLang?>
37+
let selected: Vue.Expression<CodeLang>
3838

3939
var location: ActivityClient.Location? {
4040
self.activityClient.location()
@@ -118,7 +118,7 @@ private struct UserView: HTML {
118118
> println!("{}", user.about());
119119
// \(Self.aboutDescription)
120120
"""
121-
case .none:
121+
case .markdown:
122122
h1(.aria.label("name")) {
123123
span { "#" }
124124
.inlineStyle("color", "#808080")
@@ -229,15 +229,15 @@ private struct UserView: HTML {
229229
struct ConditionalCodeLabel: HTML {
230230
let label: String
231231
let value: String
232-
let selected: Vue.Expression<CodeLang?>
232+
let selected: Vue.Expression<CodeLang>
233233

234234
var body: some HTML {
235235
CodeLang.conditionalCases(initial: selected) { lang in
236236
code {
237-
if let lang {
238-
"user.\(label)()\(lang.hasSemiColon ? ";" : "")"
239-
} else {
237+
if lang == .markdown {
240238
"[\(label)](\(value))"
239+
} else {
240+
"user.\(label)()\(lang.hasSemiColon ? ";" : "")"
241241
}
242242
}
243243
}
@@ -246,7 +246,7 @@ private struct UserView: HTML {
246246
}
247247

248248
private struct PostsView: HTML {
249-
let selected: Vue.Expression<CodeLang?>
249+
let selected: Vue.Expression<CodeLang>
250250

251251
static let description = "A curated list of projects I've worked on."
252252

@@ -268,7 +268,7 @@ private struct PostsView: HTML {
268268
// \(Self.description)
269269
let logs = fetch(Filter::All).await;
270270
"""
271-
case .none:
271+
case .markdown:
272272
h1 {
273273
span { "#" }
274274
.inlineStyle("color", "#808080")
@@ -293,7 +293,7 @@ private struct PostsView: HTML {
293293
struct PostView: HTML {
294294
let number: Int
295295
let post: Post
296-
let selected: Vue.Expression<CodeLang?>
296+
let selected: Vue.Expression<CodeLang>
297297

298298
var body: some HTML {
299299
article(.id(self.post.slug)) {
@@ -308,10 +308,10 @@ private struct PostsView: HTML {
308308
pre {
309309
a(.href("#\(self.post.slug)")) {
310310
CodeLang.conditionalCases(initial: selected) { lang in
311-
code(.class("hljs \("language-\(lang?.rawValue ?? "markdown")")")) {
311+
code(.class("hljs \("language-\(lang.rawValue)")")) {
312312
switch lang {
313-
case .none: "log-\(self.number).md"
314-
case .some: "logs[\(self.number)]"
313+
case .markdown: "log-\(self.number).md"
314+
default: "logs[\(self.number)]"
315315
}
316316
}
317317
}

Sources/Pages/Models/CodeLang.swift

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,18 @@ import HTML
33
import Vue
44

55
public enum CodeLang: String, Hashable, Encodable, CaseIterable, Sendable, RawRepresentable {
6+
case markdown
67
case swift
78
case rust
89
case typescript
910

10-
// TODO: Add markdown as valid codelang
11-
// case markdown
12-
13-
public init?(rawValue: String) {
14-
guard let value = Self.allCases.first(where: { $0.rawValue == rawValue }) else {
15-
return nil
16-
}
17-
self = value
11+
public init(rawValue: String) {
12+
self = Self.allCases.first(where: { $0.rawValue == rawValue }) ?? .markdown
1813
}
1914

2015
public var title: String {
2116
switch self {
17+
case .markdown: "Markdown"
2218
case .swift: "Swift"
2319
case .rust: "Rust"
2420
case .typescript: "TypeScript"
@@ -27,6 +23,7 @@ public enum CodeLang: String, Hashable, Encodable, CaseIterable, Sendable, RawRe
2723

2824
public var ext: String {
2925
switch self {
26+
case .markdown: "md"
3027
case .swift: "swift"
3128
case .rust: "rs"
3229
case .typescript: "ts"
@@ -35,17 +32,16 @@ public enum CodeLang: String, Hashable, Encodable, CaseIterable, Sendable, RawRe
3532

3633
var hasSemiColon: Bool {
3734
switch self {
38-
case .swift: false
35+
case .swift, .markdown: false
3936
default: true
4037
}
4138
}
4239

4340
@HTMLBuilder static func conditionalCases<Content: HTML>(
44-
initial selected: Vue.Expression<CodeLang?>,
45-
@HTMLBuilder content: (CodeLang?) -> Content
41+
initial selected: Vue.Expression<CodeLang>,
42+
@HTMLBuilder content: (CodeLang) -> Content
4643
) -> some HTML {
47-
let allCodeLangs =
48-
[selected.initialValue] + (Self.allCases + [nil]).filter { $0 != selected.initialValue }
44+
let allCodeLangs = [selected.initialValue] + Self.allCases.filter { $0 != selected.initialValue }
4945
for (idx, lang) in allCodeLangs.enumerated() {
5046
content(lang)
5147
.attribute(

Sources/Pages/NotFoundPage.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import Vue
66
public struct NotFoundPage: Page, Sendable {
77
public let title = "404 | Erik Bautista Santibanez"
88

9-
@Vue.Reactive let codeLang: CodeLang?
9+
@Vue.Reactive let codeLang: CodeLang
1010

11-
public init(codeLang: CodeLang? = .swift) {
11+
public init(codeLang: CodeLang = .markdown) {
1212
self.codeLang = codeLang
1313
}
1414

@@ -29,7 +29,7 @@ public struct NotFoundPage: Page, Sendable {
2929
}
3030

3131
private struct InnerView: HTML {
32-
let codeLang: Expression<CodeLang?>
32+
let codeLang: Expression<CodeLang>
3333

3434
private static let notFoundDescription = "The asset or page could not be found"
3535

@@ -51,7 +51,7 @@ private struct InnerView: HTML {
5151
.inlineStyle("padding-bottom", "0.5rem")
5252

5353
div {
54-
if let lang {
54+
if lang != .markdown {
5555
pre {
5656
code {
5757
"""
@@ -72,6 +72,7 @@ private struct InnerView: HTML {
7272
"""
7373
throw new Error("Not found");
7474
"""
75+
case .markdown: ""
7576
}
7677
}
7778
}
@@ -91,8 +92,10 @@ private struct InnerView: HTML {
9192
}
9293
}
9394
.inlineStyle("padding", "160px 32px")
94-
.inlineStyle("justify-self", "center")
95+
.inlineStyle("align-self", "center")
9596
}
97+
.inlineStyle("display", "flex")
98+
.inlineStyle("flex-direction", "column")
9699
}
97100
.containerStyling()
98101
.inlineStyle("width", "100%")

0 commit comments

Comments
 (0)