tera icon indicating copy to clipboard operation
tera copied to clipboard

[Feature Request] Ability to change start and stop delimiters

Open lukehsiao opened this issue 7 years ago • 8 comments

With the template delimiters as {{ }} {%, etc., is there a way to use Tera in content that heavily uses these curly braces and %? For example, if I wanted to use tera to template a LaTeX section like this:

Trying to template name.last

\newbibmacro{name:bold_author}{%
  \ifthenelse{\equal{\namepartfamily}{ {{name.last}} }}%
    {\textbf{\ifblank{\namepartgiven}{}{\namepartgiveni\space}\namepartfamily}}%
    {\ifblank{\namepartgiven}{}{\namepartgiveni\space}\namepartfamily}%
  \ifthenelse{\value{listcount}=1 \AND\value{liststop}=2}%
    {\space and\space}
    {\ifthenelse{\value{listcount}<\value{liststop}}%
      {\addcomma\space}
      {}
    }
}

Tera fails to parse with the error:

Parsing error(s):
* Failed to parse "test.tex"
  --> 27:31
   |
27 | \newbibmacro{name:bold_author}{%
   |                               ^---
   |
   = unexpected tag; expected some content

presumably due to the conflicting use of {} and %.

Using jinja options, I am able to switch delimiters:

block_start_string='~<',
block_end_string='>~',
variable_start_string='<<',
variable_end_string='>>',
comment_start_string='<#',
comment_end_string='#>',

which allows me to make a template that looks like the following and parses correctly:

\newbibmacro{name:bold_author}{%
  \ifthenelse{\equal{\namepartfamily}{ <<name.last>> }%
    {\textbf{\ifblank{\namepartgiven}{}{\namepartgiveni\space}\namepartfamily}}%
    {\ifblank{\namepartgiven}{}{\namepartgiveni\space}\namepartfamily}%
  \ifthenelse{\value{listcount}=1 \AND\value{liststop}=2}%
    {\space and\space}
    {\ifthenelse{\value{listcount}<\value{liststop}}%
      {\addcomma\space}
      {}
    }
}

But, without being able to change delimiters in Tera, am I stuck? Is it impossible to use tera in templates that already use curly braces and percentage signs?

lukehsiao avatar Sep 25 '18 04:09 lukehsiao

Is it impossible to use tera in templates that already use curly braces and percentage signs?

If you want to interpolate variables from Tera yes :/ The parser generator I am using doesn't allow passing arguments but it could be possible to hardcode an alternative parser by duplicating the grammar. You won't be able to pick which delimiters you want to use though

Keats avatar Sep 25 '18 08:09 Keats

If you want to interpolate variables from Tera yes :/

I see, I may need to look around at alternatives for now, then. Thanks for the quick response and for your work on Tera and Gutenberg!

lukehsiao avatar Sep 25 '18 15:09 lukehsiao

Re-opening it, it's worth having open to think about it

Keats avatar Sep 25 '18 18:09 Keats

Re-opening it, it's worth having open to think about it

Fair enough. The ability to switch delimiters would really open up some applications. In the rust ecosystem, there are many HTML templating crates, but I've been having a hard time trying to find one that can generalize to something like LaTeX like Jinja2 does.

lukehsiao avatar Sep 25 '18 22:09 lukehsiao

I've grown to really like Tera over the years, and still would love to template some LaTeX files. Is there any guidance you could give me if I wanted to do this, even if it involves a local fork with hard-coded changes to the delimiters?

E.g., how would I hardcode an alternative parser with different delimiters in a duplicate grammar?

lukehsiao avatar Oct 19 '22 04:10 lukehsiao

You can fork the repo and replace https://github.com/Keats/tera/blob/master/src/parser/tera.pest#L148-L155 to use your delimiters of choice

Keats avatar Oct 19 '22 08:10 Keats

I think many people see value here. The catch seems to be an implementation detail. As I understand it, the Tera parser is generated at compile time with hardcoded template delimiters.

This leaves the question: what are good ways to create a parser with user-definable template delimiters. Here are two options I see:

  1. Use a macro to generate a template parser. This would allow customization of the template delimiters.
  2. Make the parser's initialization/configuration accept custom template delimiters.

Of course, some choices of custom template delimiters might clash with other syntax. The library could check for clashes perhaps.

Of course, the above options have complexity and tradeoffs. I'm not very familiar with the idea of user customizations of parsers. Perhaps others see other ways?

xpe avatar May 09 '24 14:05 xpe

It's not really doable for v1 but it should be pretty easy for v2 to implement that.

Keats avatar May 09 '24 14:05 Keats