chiark / gitweb /
agpl.py: Include a `MANIFEST' file explaining where things came from.
[chopwood] / format.py
index 231f9223e853b3bd4e7ebcdd3adbdebf74ea520e..d6eb8964aad73d663e08e9701ddd0395fd130e26 100644 (file)
--- a/format.py
+++ b/format.py
@@ -389,6 +389,8 @@ def parse_arg():
   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.
@@ -772,7 +774,45 @@ def compile(control):
   """
   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 = ''):
@@ -833,10 +873,7 @@ def format(out, control, *args, **kw):
     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 = [],
@@ -1221,7 +1258,7 @@ class FormatIteration (BaseFormatOperation):
   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.
   """
 
@@ -1310,7 +1347,7 @@ class FormatRecursive (BaseFormatOperation):
   """
   ~?: 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).