A `+' means `the next pushed-back or positional argument'. It's useful to
be able to say this explicitly so that indexing and attribute references
can be attached to it: for example, in `~={thing}@[~={+.attr}A~]'.
+ Similarly, `@' designates the same argument, except that it is not
+ consumed.
An integer argument selects the positional argument with that index; a
negative index counts backwards from the end, as is usual in Python.
"""
Parse the whole CONTROL string, returning the corresponding formatting
operator.
+
+ A format control string consists of formatting directives, introduced by
+ the `~' character, and literal text. Literal text is simply output as-is.
+ Formatting directives may read /arguments/ which are provided as additional
+ inputs to the `format' function, and are typically items to be written to
+ the output in some form, and /parameters/, which control the formatting of
+ the arguments, and may be supplied in the control string, or themselves
+ read from arguments. A directive may also carry up to two flags, `@' and
+ `:'.
+
+ The effects of the directive are determined by the corresponding formatting
+ operation, an object found by looking up the directive's identifying
+ character in `COMPILE.opmaps', which is a list of dictionaries. The
+ character is converted to upper-case (if it is alphabetic), and then the
+ dictionaries are examined in order: the first match found wins. See the
+ description of the `Formatting protocol' for details of how formatting
+ operations work.
+
+ A formatting directive has the following syntax.
+
+ DIRECTIVE ::= `~' [PARAMS] [`=' ARG] FLAGS CHAR
+
+ PARAMS ::= PARAM [`,' PARAMS]
+
+ PARAM ::= EMPTY | INT | `'' CHAR | `v' | `!' ARG
+
+ FLAGS ::= [[ `@' | `:' ]]*
+
+ (The useful but unusual notation [[ X | Y | ... ]]* denotes a sequence of
+ items drawn from the listed alternatives, each appearing at most once. See
+ the function `parse_arg' for the syntax of ARG.)
+
+ An empty PARAM is equivalent to omitting the parameter; `!ARG' reads the
+ parameter value from the argument; `v' is equivalent to `!+', as a
+ convenient abbreviation and for Common Lisp compatibility. The `=ARG'
+ notation indicates which argument(s) should be processed by the operation:
+ the default is `=+'.
"""
+ if not isinstance(control, basestring): return control
pp = []
with COMPILE.bind(control = control, start = 0, end = len(control),
delim = ''):
raise TypeError, out
## Turn the control argument into a formatting operation.
- if isinstance(control, basestring):
- op = compile(control)
- else:
- op = control
+ op = compile(control)
## Invoke the formatting operation in the correct environment.
with FORMAT.bind(write = write, pushback = [],
then the enclosed directives are applied once even if the argument sequence
is empty.
- If the formatting directives are empty then a formatting string is fetched
+ If the formatting directives are empty then a formatting control is fetched
using the argument collector associated with the closing delimiter.
"""
"""
~?: Recursive formatting.
- Without `@', read a pair of arguments: use the first as a format string,
+ Without `@', read a pair of arguments: use the first as a format control,
and apply it to the arguments extracted from the second (which may be a
sequence or a map).