Last active
November 3, 2022 09:43
Revisions
-
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 15 additions and 8 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -59,7 +59,6 @@ extension HTMLElement { } // MARK: - resultBuilder /// HTMLを書き出すresultBuilder @resultBuilder struct HTMLBuilder { static func buildBlock(_ elements: HTMLElement...) -> String { @@ -76,7 +75,6 @@ extension HTMLElement { } // MARK: - 既存のstructの拡張 extension String: Element { func render() -> String { self @@ -90,7 +88,6 @@ extension Int: Element { } // MARK: - タグ /// Doctype struct Doctype: HTMLElement { let tag = "!DOCTYPE html" @@ -100,6 +97,7 @@ struct Doctype: HTMLElement { // 属性と内部タグを無効にするために初期化とレンダーをオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} func render() -> String { "<!DOCTYPE html>" } @@ -140,13 +138,22 @@ struct Br: HTMLElement { var attribute: [String: String]? var innerHTML: [Element]? // 内部タグを無効にするために初期化とレンダーをオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) { self.attribute = attribute } func render() -> String { // 属性 let a = attribute?.reduce(into: "") { $0 += $1.value.isEmpty ? " \($1.key)" : #" \#($1.key)="\#($1.value)""# } ?? "" return "<\(tag)\(a)>" } } // MARK: - Test // 外部で要素を作れる var p = P { "段落" } p.attribute = ["data-test1": "333"] @@ -168,10 +175,10 @@ p.attribute?["data-test2"] = "444" P() // オープンタグ P {} // クローズタグ Br() Br(["data-test3": ""]) { "内部タグは無視される" } } } } print(html()) // <!DOCTYPE html><html><head><title>タイトル</title></head><body><p style="color:red">テキスト<p data-test1="333" data-test2="444">段落</p>1</p><p><p></p><br><br data-test3></body></html> -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -97,9 +97,12 @@ struct Doctype: HTMLElement { var attribute: [String: String]? var innerHTML: [Element]? // 属性と内部タグを無効にするために初期化とレンダーをオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} func render() -> String { "<!DOCTYPE html>" } } struct Html: HTMLElement { -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -97,7 +97,7 @@ struct Doctype: HTMLElement { var attribute: [String: String]? var innerHTML: [Element]? // 属性と内部タグを無効にするために初期化をオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} } @@ -137,7 +137,7 @@ struct Br: HTMLElement { var attribute: [String: String]? var innerHTML: [Element]? // 属性と内部タグを無効にするために初期化をオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} } -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -89,7 +89,7 @@ extension Int: Element { } } // MARK: - タグ /// Doctype struct Doctype: HTMLElement { -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -165,9 +165,10 @@ p.attribute?["data-test2"] = "444" P() // オープンタグ P {} // クローズタグ Br() Br(["style": "color:red"]) { "無視される" } } } } print(html()) // <!DOCTYPE html><html><head><title>タイトル</title></head><body><p style="color:red">テキスト<p data-test1="333" data-test2="444">段落</p>1</p><p><p></p><br><br></body></html> -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 62 additions and 48 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,57 +1,81 @@ import Foundation /// 要素 protocol Element { /// HTMLを書き出すレンダー /// - Returns: HTML func render() -> String } /// HTML要素 protocol HTMLElement: Element { /// タグ名 var tag: String { get } /// 属性 var attribute: [String: String]? { get set } /// タグ内部 var innerHTML: [Element]? { get set } /// 初期化 init() /// 初期化 /// - Parameters: /// - attribute: 属性 /// - innerHTML: タグ内部 init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) } extension HTMLElement { /// 初期化のデフォルト実装 init(_ attribute: [String: String]? = nil, @ElementBuilder innerHTML: () -> [Element]) { self.init() self.innerHTML = innerHTML() self.attribute = attribute } /// レンダーのデフォルト実装 func render() -> String { // 属性と内部タグが設定されていない場合はオープンタグ if attribute == nil, innerHTML == nil { return "<\(tag)>" } // 属性 let a = attribute?.reduce(into: "") { $0 += $1.value.isEmpty ? " \($1.key)" : #" \#($1.key)="\#($1.value)""# } ?? "" // 内部タグ let i = innerHTML?.reduce(into: "") { $0 += $1.render() } ?? "" return "<\(tag)\(a)>\(i)</\(tag)>" } } // MARK: - resultBuilder /// HTMLを書き出すresultBuilder @resultBuilder struct HTMLBuilder { static func buildBlock(_ elements: HTMLElement...) -> String { elements.reduce(into: "") { $0 += $1.render() } } } /// 内部タグを取得するresultBuilder /// HTMLElementをネストさせるために使用 @resultBuilder struct ElementBuilder { static func buildBlock(_ elements: Element...) -> [Element] { elements } } // MARK: - 既存のstructの拡張 extension String: Element { func render() -> String { @@ -67,93 +91,83 @@ extension Int: Element { // MARK: - /// Doctype struct Doctype: HTMLElement { let tag = "!DOCTYPE html" var attribute: [String: String]? var innerHTML: [Element]? // 属性と内部タグを無効にするために初期化とレンダーをオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} } struct Html: HTMLElement { let tag = "html" var attribute: [String: String]? var innerHTML: [Element]? } struct Head: HTMLElement { let tag = "head" var attribute: [String: String]? var innerHTML: [Element]? } struct Title: HTMLElement { let tag = "title" var attribute: [String: String]? var innerHTML: [Element]? } struct Body: HTMLElement { let tag = "body" var attribute: [String: String]? var innerHTML: [Element]? } struct P: HTMLElement { let tag = "p" var attribute: [String: String]? var innerHTML: [Element]? } struct Br: HTMLElement { let tag = "br" var attribute: [String: String]? var innerHTML: [Element]? // 属性と内部タグを無効にするために初期化とレンダーをオーバーライド init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} } // MARK: - Test // 外部で要素を作れる var p = P { "段落" } p.attribute = ["data-test1": "333"] p.attribute?["data-test2"] = "444" // HTMLの作成 @HTMLBuilder func html() -> String { Doctype() Html { Head { Title { "タイトル" } } Body { P(["style": "color:red"]) { "テキスト" // String p 1 // Int } P() // オープンタグ P {} // クローズタグ Br() } } } print(html()) // <!DOCTYPE html><html><head><title>タイトル</title></head><body><p style="color:red">テキスト<br><p data-test2="444" data-test1="333">段落</p>1</p><p><p></p><br></body></html> -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 60 additions and 44 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ import Foundation protocol Element { @@ -6,21 +7,15 @@ protocol Element { // MARK: - @resultBuilder struct HTMLBuilder { static func buildBlock(_ elements: HTMLElement...) -> String { elements.reduce(into: "") { $0 += $1.render() } } } @resultBuilder struct ElementBuilder { static func buildBlock(_ elements: Element...) -> [Element] { elements } } @@ -29,12 +24,10 @@ protocol Element { protocol HTMLElement: Element { var tag: String { get } var attribute: [String: String]? { get set } var innerHTML: [Element]? { get set } init() init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) } extension HTMLElement { @@ -44,100 +37,123 @@ extension HTMLElement { self.attribute = attribute } func render() -> String { if attribute == nil, innerHTML == nil { return "<\(tag)>" } let a = attribute?.reduce(into: "") { $0 += $1.value.isEmpty ? " \($1.key)" : #" \#($1.key)="\#($1.value)""# } ?? "" let i = innerHTML?.reduce(into: "") { $0 += $1.render() } ?? "" return "<\(tag)\(a)>\(i)</\(tag)>" } } // MARK: - extension String: Element { func render() -> String { self } } extension Int: Element { func render() -> String { "\(self)" } } // MARK: - struct Doctype: HTMLElement { let tag = "" var innerText: String? var innerHTML: [Element]? var attribute: [String: String]? init() {} init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) {} func render() -> String { "<!DOCTYPE html>" } } struct Html: HTMLElement { let tag = "html" var innerText: String? var innerHTML: [Element]? var attribute: [String: String]? } struct Head: HTMLElement { let tag = "head" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } struct Title: HTMLElement { let tag = "title" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } struct Body: HTMLElement { let tag = "body" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } struct P: HTMLElement { let tag = "p" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } struct Span: HTMLElement { let tag = "span" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } struct Br: HTMLElement { let tag = "br" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } // MARK: - Test var span = Span { "スパン" } span.attribute = ["data-test1": "333"] span.attribute?["data-test2"] = "444" @HTMLBuilder func html() -> String { Doctype() Html { Head { Title { "title" } } Body { P(["style": "color:red"]) { "テキスト" span 1 } P() Br() } } } print(html()) // <!DOCTYPE html><html><head><title>title</title></head><body><p style="color:red">テキスト<span data-test2="444" data-test1="333">スパン</span>1</p><p><br></body></html> -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 51 additions and 31 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,113 +6,133 @@ protocol Element { // MARK: - @resultBuilder public struct HTMLBuilder { static func buildBlock(_ root: RootElement) -> String { root.render() } } @resultBuilder private struct ElementBuilder { static func buildBlock(_ element: Element...) -> [Element] { element } } @resultBuilder private struct TextBuilder { static func buildBlock(_ text: String) -> String { text } } // MARK: - protocol HTMLElement: Element { var tag: String { get } var attribute: [String: String]? { get set } var innerText: String? { get set } var innerHTML: [Element]? { get set } init() init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) init(@TextBuilder innerText: () -> String) } extension HTMLElement { init(_ attribute: [String: String]? = nil, @ElementBuilder innerHTML: () -> [Element]) { self.init() self.innerHTML = innerHTML() self.attribute = attribute } init(@TextBuilder innerText: () -> String) { self.init() self.innerText = innerText() } func render() -> String { if tag.isEmpty, let innerText { return innerText } let i: String if innerText?.isEmpty == false { i = innerText! } else { i = innerHTML?.reduce(into: "") { $0 += $1.render() } ?? "" } let a = attribute?.reduce(into: "") { $0 += #" \#($1.key)="\#($1.value)""# } return "<\(tag)\(a ?? "")>\(i)</\(tag)>" } } protocol RootElement: HTMLElement {} // MARK: - public struct Text: HTMLElement { var tag = "" var attribute: [String : String]? var innerText: String? var innerHTML: [Element]? } public struct Html: RootElement { let tag = "html" var innerText: String? var innerHTML: [Element]? var attribute: [String: String]? } public struct Head: HTMLElement { let tag = "head" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } public struct Title: HTMLElement { let tag = "title" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } public struct Body: HTMLElement { let tag = "body" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } public struct P: HTMLElement { let tag = "p" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } public struct Span: HTMLElement { let tag = "span" var attribute: [String: String]? var innerText: String? var innerHTML: [Element]? } // MARK: - Test var span = Span { "2" } span.attribute = ["data-test1": "333"] span.attribute?["data-test2"] = "444" @HTMLBuilder func html() -> String { Html { Head { Title { "title" } } Body { P(["style": "color:red"]) { Text { "1" } span Text { "3" } } P {} } -
HonmaMasaru revised this gist
Nov 3, 2022 . 1 changed file with 22 additions and 20 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,22 +4,38 @@ protocol Element { func render() -> String } // MARK: - @resultBuilder struct HTMLBuilder { static func buildBlock(_ root: RootElement) -> String { root.render() } } @resultBuilder struct ElementBuilder { static func buildBlock(_ element: Element...) -> [Element] { element } } // MARK: - protocol HTMLElement: Element { var tag: String { get } var innerHTML: [Element]? { get set } var attribute: [String: String]? { get set } init() init(_ attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]) } extension HTMLElement { init(_ attribute: [String: String]? = nil, @ElementBuilder innerHTML: () -> [Element]) { self.init() self.attribute = attribute self.innerHTML = innerHTML() } func render() -> String { let a = attribute?.reduce(into: "") { $0 += #" \#($1.key)="\#($1.value)""# } let i = innerHTML?.reduce(into: "") { $0 += $1.render() } @@ -33,7 +49,7 @@ protocol RootElement: HTMLElement {} struct Text: Element { var innerText = "" init(_ innerText: String) { self.innerText = innerText } @@ -81,20 +97,6 @@ struct Span: HTMLElement { // MARK: - var span = Span { Text("2") } span.attribute = ["data-test1": "333"] span.attribute?["data-test2"] = "444" @@ -107,7 +109,7 @@ span.attribute?["data-test2"] = "444" } } Body { P(["style": "color:red"]) { Text("1") span Text("3") -
HonmaMasaru revised this gist
Jun 12, 2021 . No changes.There are no files selected for viewing
-
HonmaMasaru created this gist
Jun 2, 2021 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,121 @@ import Foundation protocol Element { func render() -> String } protocol HTMLElement: Element { var tag: String { get } var innerHTML: [Element]? { get set } var attribute: [String: String]? { get set } init() init(attribute: [String: String]?, @ElementBuilder innerHTML: () -> [Element]?) } extension HTMLElement { init(attribute: [String: String]? = nil, @ElementBuilder innerHTML: () -> [Element]?) { self.init() self.attribute = attribute self.innerHTML = innerHTML() } func render() -> String { let a = attribute?.reduce(into: "") { $0 += #" \#($1.key)="\#($1.value)""# } let i = innerHTML?.reduce(into: "") { $0 += $1.render() } return "<\(tag)\(a ?? "")>\(i ?? "")</\(tag)>" } } protocol RootElement: HTMLElement {} // MARK: - struct Text: Element { var innerText = "" init(_ innerText: String) { self.innerText = innerText } func render() -> String { innerText } } struct Html: RootElement { let tag = "html" var attribute: [String: String]? var innerHTML: [Element]? } struct Head: HTMLElement { let tag = "head" var attribute: [String: String]? var innerHTML: [Element]? } struct Title: HTMLElement { let tag = "title" var attribute: [String: String]? var innerHTML: [Element]? } struct Body: HTMLElement { let tag = "body" var attribute: [String: String]? var innerHTML: [Element]? } struct P: HTMLElement { let tag = "p" var attribute: [String: String]? var innerHTML: [Element]? } struct Span: HTMLElement { let tag = "span" var attribute: [String: String]? var innerHTML: [Element]? } // MARK: - @resultBuilder struct HTMLBuilder { static func buildBlock(_ root: RootElement) -> String { root.render() } } @resultBuilder struct ElementBuilder { static func buildBlock(_ element: Element...) -> [Element] { element } } // MARK: - var span = Span { Text("2") } span.attribute = ["data-test1": "333"] span.attribute?["data-test2"] = "444" @HTMLBuilder func html() -> String { Html { Head { Title { Text("title") } } Body { P(attribute: ["style": "color:red"]) { Text("1") span Text("3") } P {} } } } print(html()) // <html><head><title>title</title></head><body><p style="color:red">1<span data-test2="444" data-test1="333">2</span>3</p><p></p></body></html>