2 ms·
The text/markup distinction is one I’ve been thinking a lot about recently as I’ve been both working on my own lightweight markup language, and implementing a c
by chrismorgan 4y ago
The text/markup distinction is one I’ve been thinking a lot about recently as I’ve been both working on my own lightweight markup language, and implementing a component-based website using Django/Jinja/Nunjucks/whatever-style templates. There are too many places where you end up with attribute-like syntax, but want to pass markup, and it sometimes becomes unclear whether you’re working with a string or markup, yet the two are definitely different—in HTML serialisation, one needs escaping, the other doesn’t; or in something like DOM, one’s a string and the other’s a fragment. I’ve become progressively more and more convinced that these kinds of template languages are quite bad at writing this sort of thing.
Take this example of unfortunate mixing:
{% somecomponent attr="value", title="<strong>A:</strong> B" %}
<strong>C:</strong> D
{% endsomeecomponent %}
Trouble is that you basically have at most one markup slot, but many things semantically want more than one. The closest you can generally get in such languages as these is the likes of this:
{% somecomponent attr="value" %}
<strong>A:</strong> B
{% body %}
<strong>C:</strong> D
{% endsomecomponent %}
This can be done in some such languages, but not others—and can’t be done in anything like XML. In XML, the solution would be extra nesting, which gets messy quickly:
<somecomponent attr="value">
<title>
<strong>A:</strong> B
</title>
<body>
<strong>C:</strong> D
</body>
</somecomponent>
In JSX I suppose you could do something like this, for better or for worse:
<SomeComponent attr="value" title={<><strong>A:</strong> B</>}>
<strong>C:</strong> D
</SomeComponent>
If you use a fragment/child nodes for what is logically a string value, you run the risk of people putting non-text in there; things like an href should clearly be strings, not text nodes—or else you have to decide what to do with <a><href>/<b>exam</b>ple</href>…</a>, and poorly-written DOM manipulators will surely occasionally assume the href element contains only one text node at times. But there’s then also the question of whether you want strings to be usable in text node context (probably the more pragmatic approach), or if you want to maintain a strong distinction between the two (probably the more correct approach).
For my own language, in the more macroy part (when you’re extending it beyond the basic elements), I’m maintaining a distinction between strings and markup fragments, using different delimiters for the two, with "…" for strings and {…} for fragments. I’m also treating attributes and children equivalently, having all as possibly-named children. The basic example could be something like this in my current syntax:
@somecomponent(attr: "value", title: {**A:** B}, {
**C:** D
})