jgm/djot

Templating, symbols and conditionals

Omikhleia opened this issue · 0 comments

Djot has symbols (ex. :xxx:) which were once proposed for emojis but are

by default [...] just rendered literally but may be treated specially by a filter. (For example, a filter could convert symbols to emojis. But this is not built into djot.)

In other terms, they are parsed by the Djot reader and make it into the AST, and their processing is left to intermediate Djot filters or the eventual Djot writer. In think it is a very cool feature which allows renderers to have extensibility at the leaf level. I have used them in my Djot to SILE renderer, with provisions for user-defined symbols, a few predefined symbols and contextual metadata (in my case, those are passed from the upper context (e.g. a main master document) rather than in some metadata block in the Djot file itself, but the point below likely stands too) -- You get the idea, I can use :title:, :author: etc. in my text flow and just have them expanded as "variables".

{custom-style=TitleBlock}
::::
:title:{custom-style=TitleBook}

{custom-style=TitleAuthor}
:::
By\
:author:
:::
{custom-style=TitleIlustrator}
:::
_Illustrated by :illustrator:_
:::
::::

Now what happens if my upper master document does not define some of these symbols? Surely I don't want Illustrated by :illustrator: in my output...

Of course, you could tell me: "first, don't use symbols for this; and second, most of all, this has nothing to do with Djot, use some templating engine layer in your workflow."

And it could be the right thing to do, indeed... Except that:

  • It involves an extra parsing pass on the text content...
  • Many existing template engine have a syntax that plays hard with Djot or Markdown, so it quickly gets messy to understand and read...
    • cosmo (in the Lua world) uses $, square and curly brackets (we use them for math, links and spans, attributes...)
    • mustache / lustache and alike ports use a lot of curly brackets (idem, though a bit easier to read IMHO)
    • molde (besides being very tied to Lua for conditionals) uses {{ ... }} and {% ... %} (if Djot comment syntax stays, it's confusing)
    • ...
  • They are, obviously, not aware of Djot blocks and inlines.

So I am quite tempted to extend Djot's attributes syntax with "symbol conditionals" ?symbol (existence) and !symbol (non-existence)...

{custom-style=TitleBlock}
::::
:title:{?title custom-style=TitleBook}

{?author custom-style=TitleAuthor}
:::
By\
:author:
:::
{?illustrator custom-style=TitleIlustrator}
:::
_Illustrated by :illustrator:_
:::
::::

To me, it feels more natural, less intrusive and Djot-aware. The reader parses all, so we know syntax is consistent, and the filter or renderer just picks what it needs.
What do you think?

I am tempted, admittedly, means here that I implemented a naive (quick and dirty) version of it, and played with it... But I am not saying it necessarily has to be baked into standard Djot. I am also mentioning it here to our community for the record, as using {! and {? is currently ok, but can't say what the future of Djot is and whether they'd be used eventually for something else 😸