Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit 115040e

Browse files
committed
🚧 [wip] html, rss, sitemap, svg
1 parent 516e02e commit 115040e

File tree

140 files changed

+2929
-2911
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+2929
-2911
lines changed

Package.swift

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import PackageDescription
33

44
let defaultSwiftSettings: [SwiftSetting] = [
55
.swiftLanguageMode(.v6),
6-
.enableExperimentalFeature("AvailabilityMacro=htmlSwift 1.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0"),
6+
.enableExperimentalFeature("AvailabilityMacro=swiftHTML 1.0:macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0"),
77

88
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
99
.enableUpcomingFeature("MemberImportVisibility"),
@@ -15,9 +15,9 @@ let package = Package(
1515
.library(name: "DOM", targets: ["DOM"]),
1616
.library(name: "SGML", targets: ["SGML"]),
1717
.library(name: "SwiftHTML", targets: ["SwiftHTML"]),
18-
// .library(name: "SwiftSitemap", targets: ["SwiftSitemap"]),
19-
// .library(name: "SwiftRss", targets: ["SwiftRss"]),
20-
// .library(name: "SwiftSvg", targets: ["SwiftSvg"]),
18+
.library(name: "SwiftRSS", targets: ["SwiftRSS"]),
19+
.library(name: "SwiftSitemap", targets: ["SwiftSitemap"]),
20+
.library(name: "SwiftSVG", targets: ["SwiftSVG"]),
2121
],
2222
targets: [
2323
.target(
@@ -38,28 +38,28 @@ let package = Package(
3838
],
3939
swiftSettings: defaultSwiftSettings
4040
),
41-
42-
// .target(
43-
// name: "SwiftSitemap",
44-
// dependencies: [
45-
// .target(name: "SwiftSgml")
46-
// ],
47-
// swiftSettings: defaultSwiftSettings
48-
// ),
49-
// .target(
50-
// name: "SwiftRss",
51-
// dependencies: [
52-
// .target(name: "SwiftSgml")
53-
// ],
54-
// swiftSettings: defaultSwiftSettings
55-
// ),
56-
// .target(name: "SwiftHtml", dependencies: [
57-
// .target(name: "SwiftSgml")
58-
// ]),
59-
// .target(name: "SwiftSvg", dependencies: [
60-
// .target(name: "SwiftSgml")
61-
// ]),
62-
//
41+
.target(
42+
name: "SwiftRSS",
43+
dependencies: [
44+
.target(name: "SGML")
45+
],
46+
swiftSettings: defaultSwiftSettings
47+
),
48+
.target(
49+
name: "SwiftSitemap",
50+
dependencies: [
51+
.target(name: "SGML")
52+
],
53+
swiftSettings: defaultSwiftSettings
54+
),
55+
.target(
56+
name: "SwiftSVG",
57+
dependencies: [
58+
.target(name: "SGML")
59+
],
60+
swiftSettings: defaultSwiftSettings
61+
),
62+
// MARK: - test
6363
.testTarget(
6464
name: "DOMTests",
6565
dependencies: [
@@ -78,21 +78,23 @@ let package = Package(
7878
.target(name: "SwiftHTML")
7979
]
8080
),
81-
// .testTarget(
82-
// name: "SwiftSitemapTests",
83-
// dependencies: [
84-
// .target(name: "SwiftSitemap")
85-
// ]
86-
// ),
87-
// .testTarget(name: "SwiftRssTests", dependencies: [
88-
// .target(name: "SwiftRss"),
89-
// ]),
90-
// .testTarget(name: "SwiftHtmlTests", dependencies: [
91-
// .target(name: "SwiftHtml"),
92-
// ]),
93-
// .testTarget(name: "SwiftSvgTests", dependencies: [
94-
// .target(name: "SwiftSvg"),
95-
// ]),
96-
81+
.testTarget(
82+
name: "SwiftRSSTests",
83+
dependencies: [
84+
.target(name: "SwiftRSS")
85+
]
86+
),
87+
.testTarget(
88+
name: "SwiftSitemapTests",
89+
dependencies: [
90+
.target(name: "SwiftSitemap")
91+
]
92+
),
93+
.testTarget(
94+
name: "SwiftSVGTests",
95+
dependencies: [
96+
.target(name: "SwiftSVG")
97+
]
98+
),
9799
]
98100
)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SwiftHTML
22

3-
An awesome Swift HTML DSL library using result builders.
3+
An awesome Swift HTML DSL library using result builders that closely follows the W3C standards.
44

55

66
```swift

Sources/SGML/Attribute.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ public protocol Attribute: Sendable {
55
var value: String? { get }
66
}
77

8+
public struct RawAttribute: Attribute {
9+
public var name: String
10+
public var value: String?
11+
12+
public init(
13+
name: String,
14+
value: String? = nil
15+
) {
16+
self.name = name
17+
self.value = value
18+
}
19+
}
20+
821
public struct Attributes: Sendable {
922

1023
var storage: [String: [String?]]
@@ -57,9 +70,7 @@ public struct Attributes: Sendable {
5770
// }
5871
}
5972

60-
// MARK: - internal
61-
62-
var domAttributes: [DOM.Attribute] {
73+
public var domAttributes: [DOM.Attribute] {
6374
storage.map { name, value in
6475
let values = value.compactMap { $0 }.sorted()
6576
return .init(

Sources/SGML/Renderer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public struct Renderer: Sendable {
1818
)
1919
let doctype = render(type: document.type)
2020
let doc = renderer.render(node: document.root.node)
21-
if indent > 0 {
21+
if indent > 0, !doctype.isEmpty {
2222
return doctype + "\n" + doc
2323
}
2424
return doctype + doc

Sources/SGML/Tag.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,19 @@ extension ShortTag {
4848
)
4949
}
5050
}
51+
52+
public protocol StandardTextTag: StandardTag {
53+
var text: String { get }
54+
}
55+
56+
extension StandardTextTag {
57+
58+
public var children: [Element] {
59+
[
60+
Text(
61+
text
62+
)
63+
]
64+
}
65+
66+
}

Sources/SwiftHTML/Builder.swift

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1 @@
1-
//
2-
// File.swift
3-
//
4-
//
5-
// Created by Tibor Bodecs on 12/11/2023.
6-
//
7-
8-
//private struct Group: Element {
9-
//
10-
// var children: [Element]
11-
//
12-
// var node: Node {
13-
// .group(children.compactMap { $0.node })
14-
// }
15-
//
16-
// init(_ children: [Element] = []) {
17-
// self.children = children
18-
// }
19-
//}
20-
//
21-
//@resultBuilder
22-
//public enum Builder<T> {
23-
//
24-
// public static func buildBlock(_ components: T...) -> [T] {
25-
// components
26-
// }
27-
//
28-
// public static func buildEither(first component: T) -> T {
29-
// component
30-
// }
31-
//
32-
// public static func buildEither(second component: T) -> T {
33-
// component
34-
// }
35-
//}
36-
//
37-
//extension Builder where T == Element {
38-
//
39-
// public static func buildBlock(_ components: T...) -> T {
40-
// Group(components)
41-
// }
42-
//
43-
// public static func buildOptional(_ component: T?) -> T {
44-
// component ?? Group()
45-
// }
46-
//
47-
// public static func buildArray(_ components: [T]) -> T {
48-
// Group(components)
49-
// }
50-
//
51-
// public static func buildBlock(_ components: [T]...) -> [T] {
52-
// components.flatMap { $0 }
53-
// }
54-
//
55-
// public static func buildBlock(_ components: [T]...) -> T {
56-
// Group(components.map { Group($0) })
57-
// }
58-
//
59-
// public static func buildBlock(_ components: [[T]]) -> [T] {
60-
// components.map { Group($0) }
61-
// }
62-
//}
1+
import SGML
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import SGML
2+
3+
/// https://html.spec.whatwg.org/#embedded-content
4+
public protocol EmbeddedContent: Element {
5+
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import SGML
2+
3+
/// https://html.spec.whatwg.org/#flow-content
4+
public protocol FlowContent: Element {
5+
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import SGML
2+
3+
/// https://html.spec.whatwg.org/#heading-content
4+
public protocol HeadingContent: Element {
5+
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import SGML
2+
3+
/// https://html.spec.whatwg.org/#interactive-content
4+
public protocol InteractiveContent: Element {
5+
6+
}

0 commit comments

Comments
 (0)