Create a DSL that generates HTML/XML in Swift using @dynamicMemberLookup
. (I made)
SwiftPM
It is distributed in the form of Swift PM.
https://github.com/coe/MarkUpDynamic
HTML
Write Swift in the following form.
MarkUp()
.html[MarkUp()
.body[MarkUp()
.table[MarkUp()
.tr[MarkUp()
.td[character: "one"]
.td[character: "two"]
]
]
]
].generate()
If you write Swift code with the above structure, HTML text will be generated in the following form.
<html>
<body>
<table>
<tr>
<td>one</td>
<td>two</td>
</tr>
</table>
</body>
</html>
XML
You can generate XML as well.
Connect the recipe
and the procedure
with dot access.
MarkUp(doctype: #"<?xml version="1.0" encoding="UTF-8"?>"#)
.recipe[MarkUp()
.procedure[character: "Mix all ingredients together."]
.procedure[character: "Place in the oven at 180 ° C and bake for 30 minutes."]
]
.generate()
This will generate XML in the following form.
<?xml version="1.0" encoding="UTF-8"?>
<recipe>
<procedure>Mix all ingredients together.</procedure>
<procedure>Place in the oven at 180 ° C and bake for 30 minutes.</procedure>
</recipe>
We use @dynamicMemberLookup
to generate these tags.
dynamicMemberLookup
dynamicMemberLookup is a feature added in Swift 4.2.
When @dynamicMemberLookup
is given, you can access with dots as if a proper paddy is implemented, and internally you will write the processing for dot access in the part ofsubscript (dynamicMember :)
.
In the case of the above code, subscript (dynamicMember :)
works by accessing .html
, .body
, .recipe
, etc., and the process to generate the tag is performed.
public subscript(dynamicMember member: String) -> MarkUp {
tagName(member)
}
public func tagName(_ tagName: String) -> MarkUp {
queue.append(self)
return MarkUp(tag: tagName,queue: queue)
}
Recommended Posts