mercurial/formatter.py
changeset 30560 783016005122
parent 29949 e7cacb45c4be
child 31170 e64b70c96338
equal deleted inserted replaced
30559:d83ca854fa21 30560:783016005122
     2 #
     2 #
     3 # Copyright 2012 Matt Mackall <mpm@selenic.com>
     3 # Copyright 2012 Matt Mackall <mpm@selenic.com>
     4 #
     4 #
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
       
     7 
       
     8 """Generic output formatting for Mercurial
       
     9 
       
    10 The formatter provides API to show data in various ways. The following
       
    11 functions should be used in place of ui.write():
       
    12 
       
    13 - fm.write() for unconditional output
       
    14 - fm.condwrite() to show some extra data conditionally in plain output
       
    15 - fm.data() to provide extra data to JSON or template output
       
    16 - fm.plain() to show raw text that isn't provided to JSON or template output
       
    17 
       
    18 To show structured data (e.g. date tuples, dicts, lists), apply fm.format*()
       
    19 beforehand so the data is converted to the appropriate data type. Use
       
    20 fm.isplain() if you need to convert or format data conditionally which isn't
       
    21 supported by the formatter API.
       
    22 
       
    23 To build nested structure (i.e. a list of dicts), use fm.nested().
       
    24 
       
    25 See also https://www.mercurial-scm.org/wiki/GenericTemplatingPlan
       
    26 
       
    27 fm.condwrite() vs 'if cond:':
       
    28 
       
    29 In most cases, use fm.condwrite() so users can selectively show the data
       
    30 in template output. If it's costly to build data, use plain 'if cond:' with
       
    31 fm.write().
       
    32 
       
    33 fm.nested() vs fm.formatdict() (or fm.formatlist()):
       
    34 
       
    35 fm.nested() should be used to form a tree structure (a list of dicts of
       
    36 lists of dicts...) which can be accessed through template keywords, e.g.
       
    37 "{foo % "{bar % {...}} {baz % {...}}"}". On the other hand, fm.formatdict()
       
    38 exports a dict-type object to template, which can be accessed by e.g.
       
    39 "{get(foo, key)}" function.
       
    40 
       
    41 Doctest helper:
       
    42 
       
    43 >>> def show(fn, verbose=False, **opts):
       
    44 ...     import sys
       
    45 ...     from . import ui as uimod
       
    46 ...     ui = uimod.ui()
       
    47 ...     ui.fout = sys.stdout  # redirect to doctest
       
    48 ...     ui.verbose = verbose
       
    49 ...     return fn(ui, ui.formatter(fn.__name__, opts))
       
    50 
       
    51 Basic example:
       
    52 
       
    53 >>> def files(ui, fm):
       
    54 ...     files = [('foo', 123, (0, 0)), ('bar', 456, (1, 0))]
       
    55 ...     for f in files:
       
    56 ...         fm.startitem()
       
    57 ...         fm.write('path', '%s', f[0])
       
    58 ...         fm.condwrite(ui.verbose, 'date', '  %s',
       
    59 ...                      fm.formatdate(f[2], '%Y-%m-%d %H:%M:%S'))
       
    60 ...         fm.data(size=f[1])
       
    61 ...         fm.plain('\\n')
       
    62 ...     fm.end()
       
    63 >>> show(files)
       
    64 foo
       
    65 bar
       
    66 >>> show(files, verbose=True)
       
    67 foo  1970-01-01 00:00:00
       
    68 bar  1970-01-01 00:00:01
       
    69 >>> show(files, template='json')
       
    70 [
       
    71  {
       
    72   "date": [0, 0],
       
    73   "path": "foo",
       
    74   "size": 123
       
    75  },
       
    76  {
       
    77   "date": [1, 0],
       
    78   "path": "bar",
       
    79   "size": 456
       
    80  }
       
    81 ]
       
    82 >>> show(files, template='path: {path}\\ndate: {date|rfc3339date}\\n')
       
    83 path: foo
       
    84 date: 1970-01-01T00:00:00+00:00
       
    85 path: bar
       
    86 date: 1970-01-01T00:00:01+00:00
       
    87 
       
    88 Nested example:
       
    89 
       
    90 >>> def subrepos(ui, fm):
       
    91 ...     fm.startitem()
       
    92 ...     fm.write('repo', '[%s]\\n', 'baz')
       
    93 ...     files(ui, fm.nested('files'))
       
    94 ...     fm.end()
       
    95 >>> show(subrepos)
       
    96 [baz]
       
    97 foo
       
    98 bar
       
    99 >>> show(subrepos, template='{repo}: {join(files % "{path}", ", ")}\\n')
       
   100 baz: foo, bar
       
   101 """
     7 
   102 
     8 from __future__ import absolute_import
   103 from __future__ import absolute_import
     9 
   104 
    10 import os
   105 import os
    11 
   106