mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
79e1fe3fce
@ -228,9 +228,12 @@ General Program Mode
|
||||
times_div_expr ::= unary_op_expr [ times_div_op unary_op_expr ]*
|
||||
times_div_op ::= '*' | '/'
|
||||
unary_op_expr ::= [ add_sub_op unary_op_expr ]* | expression
|
||||
expression ::= identifier | constant | function | assignment |
|
||||
expression ::= identifier | constant | function | assignment | field_reference |
|
||||
if_expression | for_expression | '(' expression_list ')'
|
||||
identifier ::= sequence of letters or ``_`` characters
|
||||
field_reference ::= '$' [ '$' ] [ '#' ] identifier
|
||||
identifier ::= id_start [ id_rest ]*
|
||||
id_start ::= letter | underscore
|
||||
id_rest ::= id_start | digit
|
||||
constant ::= " string " | ' string ' | number
|
||||
function ::= identifier '(' expression_list [ ',' expression_list ]* ')'
|
||||
assignment ::= identifier '=' top_expression
|
||||
@ -256,7 +259,7 @@ is 3.
|
||||
|
||||
The operator precedence (order of evaluation) specified by the above grammar, from highest to lowest is:
|
||||
|
||||
* Function calls, constants, parenthesized expressions, statement expressions, assignment expressions.
|
||||
* Function calls, constants, parenthesized expressions, statement expressions, assignment expressions, field references.
|
||||
* Unary plus (``+``) and minus (``-``). These operators evaluate right to left. These and all the other arithmetic operators return integers if the expression results in a fractional part equal to zero. Example: if an expression returns ``3.0`` it is changed to ``3``.
|
||||
* Multiply (``*``) and divide (``/``). These operators are associative and evaluate left to right. Use parentheses if you want to change the order of evaluation.
|
||||
* Add (``+``) and subtract (``-``). These operators are associative and evaluate left to right.
|
||||
@ -265,6 +268,15 @@ The operator precedence (order of evaluation) specified by the above grammar, fr
|
||||
* Logical and (``&&``). This operator returns '1' if both the left-hand and right-hand expressions are True, or the empty string ``''`` if either is False. It is associative, evaluates left to right, and does `short-circuiting <https://chortle.ccsu.edu/java5/Notes/chap40/ch40_2.html>`_.
|
||||
* Logical or (``||``). This operator returns ``'1'`` if either the left-hand or right-hand expression is True, or ``''`` if both are False. It is associative, evaluates left to right, and does short-circuiting. The operator is an inclusive or, returning '1' if both the left- and right-hand expressions are True.
|
||||
|
||||
**Field References**
|
||||
|
||||
A ``field_reference`` evaluates to the value of the metadata field named by lookup key that follows the ``$`` or ``$$``. Using ``$`` is equivalent to using the ``field()`` function. Using ``$$`` is equivalent to using the ``raw_field`` function. Examples::
|
||||
|
||||
* $authors ==> field('authors')
|
||||
* $#genre ==> field('#genre')
|
||||
* $$pubdate ==> raw_field('pubdate')
|
||||
* $$#my_int ==> raw_field('#my_int')
|
||||
|
||||
**If Expressions**
|
||||
|
||||
``If`` expressions first evaluate the ``condition``, which is True if it evaluates to anything other than the empty string. If the ``condition`` is True then the ``expression_list`` in the ``then`` clause is evaluated. If it is False then the ``expression_list`` in the ``elif`` or ``else`` clause is evaluated if present. The ``elif`` and ``else`` parts are optional. The words ``if``, ``then``, ``elif``, ``else``, and ``fi`` are reserved; you cannot use them as identifier names. You can put newlines and white space wherever they make sense. The ``condition`` is a ``top_expression`` not an ``expression_list``; semicolons are not allowed. The ``expression_lists`` are semicolon-separated sequences of template language top_expressions. An ``if`` expression returns the result of the last ``top_expression`` in the evaluated ``expression_list``, or '' if no expression list was evaluated.
|
||||
|
@ -578,8 +578,13 @@ class _Parser(object):
|
||||
if self.token_is_for():
|
||||
return self.for_expression()
|
||||
if self.token_is_id():
|
||||
# We have an identifier. Determine if it is a function
|
||||
id_ = self.token()
|
||||
# We have an identifier. Check if it is a field reference
|
||||
if len(id_) > 1 and id_[0] == '$':
|
||||
if id_[1] == '$':
|
||||
return RawFieldNode(ConstantNode(id_[2:]))
|
||||
return FieldNode(ConstantNode(id_[1:]))
|
||||
# Determine if it is a function
|
||||
if not self.token_op_is_lparen():
|
||||
if self.token_op_is_equals():
|
||||
# classic assignment statement
|
||||
@ -992,6 +997,7 @@ class TemplateFormatter(string.Formatter):
|
||||
(r'(\|\||&&|!)', lambda x,t: (_Parser.LEX_OP, t)), # noqa
|
||||
(r'[(),=;:\+\-*/]', lambda x,t: (_Parser.LEX_OP, t)), # noqa
|
||||
(r'-?[\d\.]+', lambda x,t: (_Parser.LEX_CONST, t)), # noqa
|
||||
(r'\$\$?#?\w+', lambda x,t: (_Parser.LEX_ID, t)), # noqa
|
||||
(r'\$', lambda x,t: (_Parser.LEX_ID, t)), # noqa
|
||||
(r'\w+', lambda x,t: (_Parser.LEX_ID, t)), # noqa
|
||||
(r'".*?((?<!\\)")', lambda x,t: (_Parser.LEX_CONST, t[1:-1])), # noqa
|
||||
|
Loading…
x
Reference in New Issue
Block a user