bug-recutils
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]