[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC] Expanded language for templates
From: |
Jose E. Marchesi |
Subject: |
[RFC] Expanded language for templates |
Date: |
Fri, 18 Dec 2020 11:53:17 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
Currently recfmt understands just one kind of mark:
{{EXPR}}
Where EXPR is any selection expression.
It is possible to express conditionals and other complex operations in a
selection expression, which are also useful in template substitutions.
But what is good for selections may not be that good for substitutions,
so here I propose an expanded design for templates.
Note that in this new designt he current {{EXPR}} is still supported.
Opinions?
** Recutils Template Language
A template consists on unrestricted text and marks. Marks are anything
enclosed between {{ and }} characters. Anything that is not part of a mark
is literally copied to the output.
Marks are processed by the templates engine and replaced by some text. The
actual text depends on the type of mark. Supported marks are expression
marks, comment marks, conditional marks, looping marks and inclusion marks.
Those are described in the following subsections.
`{{' and `}}' sequences that are part of the unrestricted text part shall
be written as `{{{' and `}}}' respectively.
*** Expression marks
Expression marks contain selection expressions:
: {{EXPR}}
The enclosed selection expression can vary from simple field names to
complex expressions. Examples are:
: {{Name}} => Jose E. Marchesi
: {{"Mr. " & Name}} => Mr. Jose E. Marchesi
: Number of emails: {{#Email}} => Number of emails: 2
If the selection expression into a mark generates the empty string then
the mark is replaced with the empty string.
*** Comment marks
Marks of the form
: {{! foobar !}}
contain comments. The text enclosed in the mark is ignored, being
replaced with the empty string. This is useful to comment out parts of
template files. Note that the ! character also appears before the }} in
order to support nested marks. Comment marks can be nested as well, but
in that case they must be balanced:
: {{!
: This was part of the template:
: {! a list of articles !}
: ...
: !}}
Note that the ! characters shall appear immediately after {{ and
immediately before }}.
*** Conditional marks
The conditional marks allow to make if-then-else structures in the
template. They are used like:
: {{@if EXPR}}
: This is the if part.
: {{@elif EXPR}}
: Another if part.
: {{@else}}
: If nothing else...
: {{@end}}
The semantics of each sections are the expected ones. The @elif and @else
marks are optional, and many @elif marks can be used. The @end mark shall
be present.
*** Looping marks
The looping marks allow to code loop structures in the template. There
are two flavors: for and foreach.
The 'foreach' loop allows to associate a template variable with all the
consecutive values of a record field. The synopsis is:
: {{@foreach VAR FIELD_NAME}}
: ...
: {{@end}}
The mark is replaced with the concatenated bodies resulting from applying
its contents, with @VAR being replaced by the consecutive values of
FIELD_NAME in the current record. For example, we could make a bullet
list of articles using the following template:
: {{@foreach A Article}}
: - {{@A}}
: {{@end}}
It is also possible to use a regular expression as the second argument to
@foreach. In that case any field whose name matches with the regular
expression is processed. For example, this is how we would make a bullet
list with all the fields in a record:
: {{@foreach A /.*/}}
: - {{@A}}
: {{@end}}
Note that {{@A}} in the examples above is an expression mark. The @VAR
constructions are replaced only when they are found in expression marks,
before the actual expression is computed. For obvious reasons VAR cannot
be equal to 'if', 'elif', 'else', 'for', 'foreach' or 'end'.
The second flavor of looping templates is the more general 'for' loop.
The synopsis is:
: {{@for VAR EXPR_MIN..EXPR_MAX}}
: ...
: {{@end}}
The mark is replaced with the concatenated bodies resulting from applying
its contents, with @VAR being replaced by the integral numbers in the
range [EXPR_MIN,EXPR_MAX], both sides included. Both EXPR_MIN and
EXPR_MAX shall be selection expressions whose results can be interpreted
as an integer. Negative integers are allowed, and in case EXPR_MIN is
bigger than EXPR_MAX then the count will be performed downwards. An
example of the usage of those marks is:
: {{@for I 0..#Article - 1}}
: - {{Article[@I]}}
: {{@end}}
Those marks are equivalent to the 'foreach' example above. If we wanted
to list the articles downwards we would reverse the expressions:
: {{@for I #Article..0}}
: - {{Article[@I]}}
: {{@end}}
Note that the '..' characters separating both selection expressions shall
not be separated.
*** Inclusion marks
Inclusion marks allow to decompose complex templates into simpler
templates stored in other files. The synopsis is:
: {{< FILE}}
where FILE is the path of a file. The mark is replaced by the contents of
the file once they have been processed by the templates engine. The path
may be either absolute or relative. In the later case the file is
relative to the current working directory of the process running the
template engine.
- [RFC] Expanded language for templates,
Jose E. Marchesi <=