Skip to content

Instantly share code, notes, and snippets.

@venkatperi
Created June 18, 2014 01:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save venkatperi/6a89c9b8c49e4b5d7736 to your computer and use it in GitHub Desktop.
Save venkatperi/6a89c9b8c49e4b5d7736 to your computer and use it in GitHub Desktop.
Swift Builder
import Foundation
struct Builder {
typealias Attributes = Dictionary<String, AnyObject>
typealias Block = () -> ()
typealias Visitor = (Node) -> ()
class Node {
var name : String
var parent: Node? { didSet { level = parent!.level + 1} }
var children = Node[]()
var attr = Attributes()
var block: Block?
var level = 0
var value : AnyObject?
init( name: String) {
self.name = name
}
func visit(before: Visitor?, after: Visitor?) {
if let v = before { v(self) }
for c in children { c.visit( before, after ) }
if let v = after { v(self) }
}
}
static let root = Node(name: "root")
static var current = root
static func node(name: String, attr : Attributes?, value: AnyObject?, block: Block ) {
var n = Node(name: name)
n.parent = current
if let a = attr { n.attr = a }
n.block = block
n.value = value
current.children += n
current = n
block()
if let p = current.parent { current = p }
}
static func visit(before: Visitor?, after: Visitor?) {
for c in root.children { c.visit(before, after) }
}
}
func html(block: ()->()) { html(nil, block) }
func html(attr: Builder.Attributes?, block: ()->()) { Builder.node("html", attr: attr, value: nil, block) }
func body(block: ()->()) { body(nil, block) }
func body(attr: Builder.Attributes? , block: ()->()) { Builder.node("body", attr: attr, value: nil, block) }
func head(block: ()->()) { head(nil, block) }
func head(attr: Builder.Attributes?, block: ()->()) { Builder.node("head", attr: attr, value: nil, block) }
func title(block: ()->()) { title(nil, nil, block) }
func title(attr: Builder.Attributes?, block: ()->()) { title(attr, nil, block) }
func title(value: AnyObject?, block: ()->()) { title(nil, value, block) }
func title(attr: Builder.Attributes?, value: AnyObject?, block: ()->()) { Builder.node("title", attr: attr, value: value, block) }
func div(block: ()->()) { div(nil, nil, block) }
func div(attr: Builder.Attributes?, block: ()->()) { div(attr, nil, block) }
func div(value: AnyObject?, block: ()->()) { div(nil, value, block) }
func div(attr: Builder.Attributes?, value: AnyObject?, block: ()->()) { Builder.node("div", attr: attr, value: value, block) }
func p(block: ()->()) { p(nil, nil, block) }
func p(attr: Builder.Attributes?, block: ()->()) { p(attr, nil, block) }
func p(value: AnyObject?, block: ()->()) { p(nil, value, block) }
func p(attr: Builder.Attributes?, value: AnyObject?, block: ()->()) { Builder.node("p", attr: attr, value: value, block) }
func a(block: ()->()) { a(nil, nil, block) }
func a(attr: Builder.Attributes?, block: ()->()) { a(attr, nil, block) }
func a(value: AnyObject?, block: ()->()) { a(nil, value, block) }
func a(attr: Builder.Attributes?, value: AnyObject?, block: ()->()) { Builder.node("a", attr: attr, value: value, block) }
func visit(before: Builder.Visitor?, after: Builder.Visitor? = nil) {
Builder.visit(before, after)
}
html {
head {
title( "Page Title" ) {}
}
body(["class":"bodyClass"]) {
for i in 0..3 {
div(["id":"div_\(i)"]) {
p("Click ") {
a(["href":"http://www.example.com/link\(i).html"], "link \(i+1)") {}
}
}
}
}
}
func repeat( item: String, n: Int) -> String {
var s = ""
for var i:Int=0; i<n; i++ { s += item }
return s
}
visit( {
let node = $0
let r = repeat(" ", node.level*2)
var tag = "\(r)<\(node.name)"
for a in node.attr { tag += " \"\(a.0)\"=\"\(a.1)\"" }
tag += ">"
if let v:AnyObject = node.value { tag += "\(v)" }
println(tag)
},
{
let node = $0
let r = repeat(" ", node.level*2)
var tag = "\(r)</\(node.name)>"
println(tag)
} )
println([1,2,3,4,5].count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment