comparison mercurial/formatter.py @ 30560:783016005122

formatter: add overview of API and example as doctest
author Yuya Nishihara <yuya@tcha.org>
date Sat, 22 Oct 2016 15:02:11 +0900
parents e7cacb45c4be
children e64b70c96338
comparison
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