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