An HTML DSL

Episode #28 • Sep 3, 2018 • Subscriber-Only

This week we apply domain-specific languages to a very real-world problem: representing and rendering HTML. We code up a simple but powerful solution that forms the foundation of what we use to build the Point-Free website.

An HTML DSL
Introduction
00:05
HTML in types
01:13
HTML in functions
04:19
HTML interpreted
10:42
HTML transformed
15:04
What's the point?
19:04

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Introduction

In a couple recent episodes, we introduced the idea of domain specific languages, often abbreviated DSLs, which are languages that are highly tuned to a specific task. We then introduced the idea of embedded DSLs (or EDSLs), which are domain specific languages that are hosted, or written, in a more general purpose language, like Swift.

To get comfortable with the idea, we embedded some basic arithmetic in the Swift type system. Using a DSL helped us separate the pure, data-driven description of a domain problem from the impure, run-time interpretation of that data.

But arithmetic was a bit of a toy example, though, so today we’re going to embed a more real-world domain problem in Swift, HTML, by building the same DSL that we use to power the Point-Free web site!

This episode is for subscribers only.

Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

Already a subscriber? Log in

Exercises

  1. Our render function currently prints an extra space when attributes aren’t present: "<header ></header>". Fix the render function so that render(header([])) == "<header></header>".

  2. HTML specifies a number of “void elements” (elements that have no closing tag). This includes the img element in our example. Update the render function to omit the closing tag on void elements.

  3. Our render function is currently unsafe: text node content isn’t escaped, which means it could be susceptible to cross-site scripting attacks. Ensure that text nodes are properly escaped during rendering.

  4. Ensure that attribute nodes are properly escaped during rendering.

  5. Write a function redacted, which transforms a Node and its children, replacing all non-whitespace characters with a redacted character: .

  6. Write a function removingStyles, which removes all style nodes and attributes.

  7. Write a function removingScripts, which removes all script nodes and attributes with the on prefix (like onclick).

  8. Write a function plainText, which transforms HTML into human-readable text, which might be useful for rendering plain-text emails from HTML content.

  9. One of the most popular way of rendering HTML is to use a templating language (Swift, for example, has Stencil). What are some of the pros and cons of using a templating language over a DSL.

References

Open sourcing swift-html: A Type-Safe Alternative to Templating Languages in Swift

Brandon Williams & Stephen Celis • Monday Nov 12, 2018

After developing the ideas of DSLs in a series of episodes ( part 1 and part 2), we open sourced our own DSL library for constructing HTML in Swift. We use this library heavily for building every page on this very website, and it unlocks a lot of wonderful transformations and opportunities for code reuse.

Downloads

Sample Code

0028-html-dsl