rev |
line source |
bos@559
|
1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
|
bos@559
|
2
|
bos@559
|
3 <chapter id="chap:template">
|
bos@572
|
4 <?dbhtml filename="customizing-the-output-of-mercurial.html"?>
|
bos@559
|
5 <title>Customising the output of Mercurial</title>
|
bos@559
|
6
|
bos@584
|
7 <para id="x_578">Mercurial provides a powerful mechanism to let you control how
|
bos@559
|
8 it displays information. The mechanism is based on templates.
|
bos@559
|
9 You can use templates to generate specific output for a single
|
bos@559
|
10 command, or to customise the entire appearance of the built-in web
|
bos@559
|
11 interface.</para>
|
bos@559
|
12
|
bos@559
|
13 <sect1 id="sec:style">
|
bos@559
|
14 <title>Using precanned output styles</title>
|
bos@559
|
15
|
bos@584
|
16 <para id="x_579">Packaged with Mercurial are some output styles that you can
|
bos@559
|
17 use immediately. A style is simply a precanned template that
|
bos@559
|
18 someone wrote and installed somewhere that Mercurial can
|
bos@559
|
19 find.</para>
|
bos@559
|
20
|
bos@584
|
21 <para id="x_57a">Before we take a look at Mercurial's bundled styles, let's
|
bos@559
|
22 review its normal output.</para>
|
bos@559
|
23
|
bos@567
|
24 &interaction.template.simple.normal;
|
bos@559
|
25
|
bos@584
|
26 <para id="x_57b">This is somewhat informative, but it takes up a lot of
|
bos@559
|
27 space&emdash;five lines of output per changeset. The
|
bos@559
|
28 <literal>compact</literal> style reduces this to three lines,
|
bos@559
|
29 presented in a sparse manner.</para>
|
bos@559
|
30
|
bos@567
|
31 &interaction.template.simple.compact;
|
bos@559
|
32
|
bos@584
|
33 <para id="x_57c">The <literal>changelog</literal> style hints at the
|
bos@559
|
34 expressive power of Mercurial's templating engine. This style
|
bos@559
|
35 attempts to follow the GNU Project's changelog
|
bos@559
|
36 guidelines<citation>web:changelog</citation>.</para>
|
bos@559
|
37
|
bos@567
|
38 &interaction.template.simple.changelog;
|
bos@559
|
39
|
bos@584
|
40 <para id="x_57d">You will not be shocked to learn that Mercurial's default
|
bos@559
|
41 output style is named <literal>default</literal>.</para>
|
bos@559
|
42
|
bos@559
|
43 <sect2>
|
bos@559
|
44 <title>Setting a default style</title>
|
bos@559
|
45
|
bos@584
|
46 <para id="x_57e">You can modify the output style that Mercurial will use
|
bos@580
|
47 for every command by editing your <filename
|
bos@580
|
48 role="special">~/.hgrc</filename> file, naming the style
|
bos@580
|
49 you would prefer to use.</para>
|
bos@580
|
50
|
bos@580
|
51 <programlisting>[ui]
|
bos@580
|
52 style = compact</programlisting>
|
bos@559
|
53
|
bos@584
|
54 <para id="x_57f">If you write a style of your own, you can use it by either
|
bos@559
|
55 providing the path to your style file, or copying your style
|
bos@559
|
56 file into a location where Mercurial can find it (typically
|
bos@559
|
57 the <literal>templates</literal> subdirectory of your
|
bos@559
|
58 Mercurial install directory).</para>
|
bos@559
|
59 </sect2>
|
bos@559
|
60 </sect1>
|
bos@682
|
61
|
bos@559
|
62 <sect1>
|
bos@559
|
63 <title>Commands that support styles and templates</title>
|
bos@559
|
64
|
bos@584
|
65 <para id="x_580">All of Mercurial's
|
bos@559
|
66 <quote><literal>log</literal>-like</quote> commands let you use
|
bos@559
|
67 styles and templates: <command role="hg-cmd">hg
|
bos@559
|
68 incoming</command>, <command role="hg-cmd">hg log</command>,
|
bos@559
|
69 <command role="hg-cmd">hg outgoing</command>, and <command
|
bos@559
|
70 role="hg-cmd">hg tip</command>.</para>
|
bos@559
|
71
|
bos@584
|
72 <para id="x_581">As I write this manual, these are so far the only commands
|
bos@559
|
73 that support styles and templates. Since these are the most
|
bos@559
|
74 important commands that need customisable output, there has been
|
bos@559
|
75 little pressure from the Mercurial user community to add style
|
bos@559
|
76 and template support to other commands.</para>
|
bos@559
|
77
|
bos@559
|
78 </sect1>
|
bos@559
|
79 <sect1>
|
bos@559
|
80 <title>The basics of templating</title>
|
bos@559
|
81
|
bos@584
|
82 <para id="x_582">At its simplest, a Mercurial template is a piece of text.
|
bos@559
|
83 Some of the text never changes, while other parts are
|
bos@559
|
84 <emphasis>expanded</emphasis>, or replaced with new text, when
|
bos@559
|
85 necessary.</para>
|
bos@559
|
86
|
bos@584
|
87 <para id="x_583">Before we continue, let's look again at a simple example of
|
bos@559
|
88 Mercurial's normal output.</para>
|
bos@559
|
89
|
bos@567
|
90 &interaction.template.simple.normal;
|
bos@559
|
91
|
bos@584
|
92 <para id="x_584">Now, let's run the same command, but using a template to
|
bos@559
|
93 change its output.</para>
|
bos@559
|
94
|
bos@567
|
95 &interaction.template.simple.simplest;
|
bos@559
|
96
|
bos@584
|
97 <para id="x_585">The example above illustrates the simplest possible
|
bos@559
|
98 template; it's just a piece of static text, printed once for
|
bos@559
|
99 each changeset. The <option
|
bos@559
|
100 role="hg-opt-log">--template</option> option to the <command
|
bos@559
|
101 role="hg-cmd">hg log</command> command tells Mercurial to use
|
bos@559
|
102 the given text as the template when printing each
|
bos@559
|
103 changeset.</para>
|
bos@559
|
104
|
bos@584
|
105 <para id="x_586">Notice that the template string above ends with the text
|
bos@559
|
106 <quote><literal>\n</literal></quote>. This is an
|
bos@559
|
107 <emphasis>escape sequence</emphasis>, telling Mercurial to print
|
bos@559
|
108 a newline at the end of each template item. If you omit this
|
bos@559
|
109 newline, Mercurial will run each piece of output together. See
|
bos@592
|
110 <xref linkend="sec:template:escape"/> for more details
|
bos@559
|
111 of escape sequences.</para>
|
bos@559
|
112
|
bos@584
|
113 <para id="x_587">A template that prints a fixed string of text all the time
|
bos@559
|
114 isn't very useful; let's try something a bit more
|
bos@559
|
115 complex.</para>
|
bos@559
|
116
|
bos@567
|
117 &interaction.template.simple.simplesub;
|
bos@559
|
118
|
bos@584
|
119 <para id="x_588">As you can see, the string
|
bos@559
|
120 <quote><literal>{desc}</literal></quote> in the template has
|
bos@559
|
121 been replaced in the output with the description of each
|
bos@559
|
122 changeset. Every time Mercurial finds text enclosed in curly
|
bos@559
|
123 braces (<quote><literal>{</literal></quote> and
|
bos@592
|
124 <quote><literal>}</literal></quote>), it will try to replace the
|
bos@592
|
125 braces and text with the expansion of whatever is inside. To
|
bos@592
|
126 print a literal curly brace, you must escape it, as described in
|
bos@592
|
127 <xref linkend="sec:template:escape"/>.</para>
|
bos@682
|
128 </sect1>
|
bos@682
|
129
|
bos@559
|
130 <sect1 id="sec:template:keyword">
|
bos@559
|
131 <title>Common template keywords</title>
|
bos@559
|
132
|
bos@584
|
133 <para id="x_589">You can start writing simple templates immediately using the
|
bos@559
|
134 keywords below.</para>
|
bos@559
|
135
|
bos@559
|
136 <itemizedlist>
|
bos@584
|
137 <listitem><para id="x_58a"><literal
|
bos@559
|
138 role="template-keyword">author</literal>: String. The
|
bos@559
|
139 unmodified author of the changeset.</para>
|
bos@559
|
140 </listitem>
|
bos@584
|
141 <listitem><para id="x_58b"><literal
|
bos@559
|
142 role="template-keyword">branches</literal>: String. The
|
bos@559
|
143 name of the branch on which the changeset was committed.
|
bos@559
|
144 Will be empty if the branch name was
|
bos@559
|
145 <literal>default</literal>.</para>
|
bos@559
|
146 </listitem>
|
bos@584
|
147 <listitem><para id="x_58c"><literal role="template-keyword">date</literal>:
|
bos@559
|
148 Date information. The date when the changeset was
|
bos@559
|
149 committed. This is <emphasis>not</emphasis> human-readable;
|
bos@559
|
150 you must pass it through a filter that will render it
|
bos@592
|
151 appropriately. See <xref
|
bos@559
|
152 linkend="sec:template:filter"/> for more information
|
bos@559
|
153 on filters. The date is expressed as a pair of numbers. The
|
bos@559
|
154 first number is a Unix UTC timestamp (seconds since January
|
bos@559
|
155 1, 1970); the second is the offset of the committer's
|
bos@559
|
156 timezone from UTC, in seconds.</para>
|
bos@559
|
157 </listitem>
|
bos@584
|
158 <listitem><para id="x_58d"><literal role="template-keyword">desc</literal>:
|
bos@559
|
159 String. The text of the changeset description.</para>
|
bos@559
|
160 </listitem>
|
bos@584
|
161 <listitem><para id="x_58e"><literal
|
bos@559
|
162 role="template-keyword">files</literal>: List of strings.
|
bos@559
|
163 All files modified, added, or removed by this
|
bos@559
|
164 changeset.</para>
|
bos@559
|
165 </listitem>
|
bos@584
|
166 <listitem><para id="x_58f"><literal
|
bos@559
|
167 role="template-keyword">file_adds</literal>: List of
|
bos@559
|
168 strings. Files added by this changeset.</para>
|
bos@559
|
169 </listitem>
|
bos@584
|
170 <listitem><para id="x_590"><literal
|
bos@559
|
171 role="template-keyword">file_dels</literal>: List of
|
bos@559
|
172 strings. Files removed by this changeset.</para>
|
bos@559
|
173 </listitem>
|
bos@584
|
174 <listitem><para id="x_591"><literal role="template-keyword">node</literal>:
|
bos@559
|
175 String. The changeset identification hash, as a
|
bos@559
|
176 40-character hexadecimal string.</para>
|
bos@559
|
177 </listitem>
|
bos@584
|
178 <listitem><para id="x_592"><literal
|
bos@559
|
179 role="template-keyword">parents</literal>: List of
|
bos@559
|
180 strings. The parents of the changeset.</para>
|
bos@559
|
181 </listitem>
|
bos@584
|
182 <listitem><para id="x_593"><literal role="template-keyword">rev</literal>:
|
bos@559
|
183 Integer. The repository-local changeset revision
|
bos@559
|
184 number.</para>
|
bos@559
|
185 </listitem>
|
bos@584
|
186 <listitem><para id="x_594"><literal role="template-keyword">tags</literal>:
|
bos@559
|
187 List of strings. Any tags associated with the
|
bos@559
|
188 changeset.</para>
|
bos@559
|
189 </listitem></itemizedlist>
|
bos@559
|
190
|
bos@584
|
191 <para id="x_595">A few simple experiments will show us what to expect when we
|
bos@559
|
192 use these keywords; you can see the results below.</para>
|
bos@559
|
193
|
bos@567
|
194 &interaction.template.simple.keywords;
|
bos@559
|
195
|
bos@584
|
196 <para id="x_596">As we noted above, the date keyword does not produce
|
bos@559
|
197 human-readable output, so we must treat it specially. This
|
bos@559
|
198 involves using a <emphasis>filter</emphasis>, about which more
|
bos@592
|
199 in <xref linkend="sec:template:filter"/>.</para>
|
bos@559
|
200
|
bos@567
|
201 &interaction.template.simple.datekeyword;
|
bos@682
|
202 </sect1>
|
bos@682
|
203
|
bos@559
|
204 <sect1 id="sec:template:escape">
|
bos@559
|
205 <title>Escape sequences</title>
|
bos@559
|
206
|
bos@584
|
207 <para id="x_597">Mercurial's templating engine recognises the most commonly
|
bos@559
|
208 used escape sequences in strings. When it sees a backslash
|
bos@559
|
209 (<quote><literal>\</literal></quote>) character, it looks at the
|
bos@559
|
210 following character and substitutes the two characters with a
|
bos@559
|
211 single replacement, as described below.</para>
|
bos@559
|
212
|
bos@559
|
213 <itemizedlist>
|
bos@584
|
214 <listitem><para id="x_598"><literal>\</literal>:
|
bos@559
|
215 Backslash, <quote><literal>\</literal></quote>, ASCII
|
bos@559
|
216 134.</para>
|
bos@559
|
217 </listitem>
|
bos@584
|
218 <listitem><para id="x_599"><literal>\n</literal>: Newline,
|
bos@559
|
219 ASCII 12.</para>
|
bos@559
|
220 </listitem>
|
bos@584
|
221 <listitem><para id="x_59a"><literal>\r</literal>: Carriage
|
bos@559
|
222 return, ASCII 15.</para>
|
bos@559
|
223 </listitem>
|
bos@584
|
224 <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII
|
bos@559
|
225 11.</para>
|
bos@559
|
226 </listitem>
|
bos@584
|
227 <listitem><para id="x_59c"><literal>\v</literal>: Vertical
|
bos@559
|
228 tab, ASCII 13.</para>
|
bos@559
|
229 </listitem>
|
bos@584
|
230 <listitem><para id="x_59d"><literal>{</literal>: Open curly
|
bos@559
|
231 brace, <quote><literal>{</literal></quote>, ASCII
|
bos@559
|
232 173.</para>
|
bos@559
|
233 </listitem>
|
bos@584
|
234 <listitem><para id="x_59e"><literal>}</literal>: Close curly
|
bos@559
|
235 brace, <quote><literal>}</literal></quote>, ASCII
|
bos@559
|
236 175.</para>
|
bos@559
|
237 </listitem></itemizedlist>
|
bos@559
|
238
|
bos@584
|
239 <para id="x_59f">As indicated above, if you want the expansion of a template
|
bos@559
|
240 to contain a literal <quote><literal>\</literal></quote>,
|
bos@559
|
241 <quote><literal>{</literal></quote>, or
|
bos@559
|
242 <quote><literal>{</literal></quote> character, you must escape
|
bos@559
|
243 it.</para>
|
bos@682
|
244 </sect1>
|
bos@682
|
245
|
bos@559
|
246 <sect1 id="sec:template:filter">
|
bos@559
|
247 <title>Filtering keywords to change their results</title>
|
bos@559
|
248
|
bos@584
|
249 <para id="x_5a0">Some of the results of template expansion are not
|
bos@559
|
250 immediately easy to use. Mercurial lets you specify an optional
|
bos@559
|
251 chain of <emphasis>filters</emphasis> to modify the result of
|
bos@559
|
252 expanding a keyword. You have already seen a common filter,
|
bos@559
|
253 <literal role="template-kw-filt-date">isodate</literal>, in
|
bos@559
|
254 action above, to make a date readable.</para>
|
bos@559
|
255
|
bos@584
|
256 <para id="x_5a1">Below is a list of the most commonly used filters that
|
bos@559
|
257 Mercurial supports. While some filters can be applied to any
|
bos@559
|
258 text, others can only be used in specific circumstances. The
|
bos@559
|
259 name of each filter is followed first by an indication of where
|
bos@559
|
260 it can be used, then a description of its effect.</para>
|
bos@559
|
261
|
bos@559
|
262 <itemizedlist>
|
bos@584
|
263 <listitem><para id="x_5a2"><literal
|
bos@559
|
264 role="template-filter">addbreaks</literal>: Any text. Add
|
bos@559
|
265 an XHTML <quote><literal><br/></literal></quote> tag
|
bos@559
|
266 before the end of every line except the last. For example,
|
bos@559
|
267 <quote><literal>foo\nbar</literal></quote> becomes
|
bos@559
|
268 <quote><literal>foo<br/>\nbar</literal></quote>.</para>
|
bos@559
|
269 </listitem>
|
bos@584
|
270 <listitem><para id="x_5a3"><literal
|
bos@559
|
271 role="template-kw-filt-date">age</literal>: <literal
|
bos@559
|
272 role="template-keyword">date</literal> keyword. Render
|
bos@559
|
273 the age of the date, relative to the current time. Yields a
|
bos@559
|
274 string like <quote><literal>10
|
bos@559
|
275 minutes</literal></quote>.</para>
|
bos@559
|
276 </listitem>
|
bos@584
|
277 <listitem><para id="x_5a4"><literal
|
bos@559
|
278 role="template-filter">basename</literal>: Any text, but
|
bos@559
|
279 most useful for the <literal
|
bos@559
|
280 role="template-keyword">files</literal> keyword and its
|
bos@559
|
281 relatives. Treat the text as a path, and return the
|
bos@559
|
282 basename. For example,
|
bos@559
|
283 <quote><literal>foo/bar/baz</literal></quote> becomes
|
bos@559
|
284 <quote><literal>baz</literal></quote>.</para>
|
bos@559
|
285 </listitem>
|
bos@584
|
286 <listitem><para id="x_5a5"><literal
|
bos@559
|
287 role="template-kw-filt-date">date</literal>: <literal
|
bos@559
|
288 role="template-keyword">date</literal> keyword. Render a
|
bos@559
|
289 date in a similar format to the Unix <literal
|
bos@559
|
290 role="template-keyword">date</literal> command, but with
|
bos@559
|
291 timezone included. Yields a string like <quote><literal>Mon
|
bos@559
|
292 Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
|
bos@559
|
293 </listitem>
|
bos@584
|
294 <listitem><para id="x_5a6"><literal
|
bos@559
|
295 role="template-kw-filt-author">domain</literal>: Any text,
|
bos@559
|
296 but most useful for the <literal
|
bos@559
|
297 role="template-keyword">author</literal> keyword. Finds
|
bos@559
|
298 the first string that looks like an email address, and
|
bos@559
|
299 extract just the domain component. For example,
|
bos@559
|
300 <quote><literal>Bryan O'Sullivan
|
bos@559
|
301 <bos@serpentine.com></literal></quote> becomes
|
bos@559
|
302 <quote><literal>serpentine.com</literal></quote>.</para>
|
bos@559
|
303 </listitem>
|
bos@584
|
304 <listitem><para id="x_5a7"><literal
|
bos@559
|
305 role="template-kw-filt-author">email</literal>: Any text,
|
bos@559
|
306 but most useful for the <literal
|
bos@559
|
307 role="template-keyword">author</literal> keyword. Extract
|
bos@559
|
308 the first string that looks like an email address. For
|
bos@559
|
309 example, <quote><literal>Bryan O'Sullivan
|
bos@559
|
310 <bos@serpentine.com></literal></quote> becomes
|
bos@559
|
311 <quote><literal>bos@serpentine.com</literal></quote>.</para>
|
bos@559
|
312 </listitem>
|
bos@584
|
313 <listitem><para id="x_5a8"><literal
|
bos@559
|
314 role="template-filter">escape</literal>: Any text.
|
bos@559
|
315 Replace the special XML/XHTML characters
|
bos@559
|
316 <quote><literal>&</literal></quote>,
|
bos@559
|
317 <quote><literal><</literal></quote> and
|
bos@559
|
318 <quote><literal>></literal></quote> with XML
|
bos@559
|
319 entities.</para>
|
bos@559
|
320 </listitem>
|
bos@584
|
321 <listitem><para id="x_5a9"><literal
|
bos@559
|
322 role="template-filter">fill68</literal>: Any text. Wrap
|
bos@559
|
323 the text to fit in 68 columns. This is useful before you
|
bos@559
|
324 pass text through the <literal
|
bos@559
|
325 role="template-filter">tabindent</literal> filter, and
|
bos@559
|
326 still want it to fit in an 80-column fixed-font
|
bos@559
|
327 window.</para>
|
bos@559
|
328 </listitem>
|
bos@584
|
329 <listitem><para id="x_5aa"><literal
|
bos@559
|
330 role="template-filter">fill76</literal>: Any text. Wrap
|
bos@559
|
331 the text to fit in 76 columns.</para>
|
bos@559
|
332 </listitem>
|
bos@584
|
333 <listitem><para id="x_5ab"><literal
|
bos@559
|
334 role="template-filter">firstline</literal>: Any text.
|
bos@559
|
335 Yield the first line of text, without any trailing
|
bos@559
|
336 newlines.</para>
|
bos@559
|
337 </listitem>
|
bos@584
|
338 <listitem><para id="x_5ac"><literal
|
bos@559
|
339 role="template-kw-filt-date">hgdate</literal>: <literal
|
bos@559
|
340 role="template-keyword">date</literal> keyword. Render
|
bos@559
|
341 the date as a pair of readable numbers. Yields a string
|
bos@559
|
342 like <quote><literal>1157407993
|
bos@559
|
343 25200</literal></quote>.</para>
|
bos@559
|
344 </listitem>
|
bos@584
|
345 <listitem><para id="x_5ad"><literal
|
bos@559
|
346 role="template-kw-filt-date">isodate</literal>: <literal
|
bos@559
|
347 role="template-keyword">date</literal> keyword. Render
|
bos@559
|
348 the date as a text string in ISO 8601 format. Yields a
|
bos@559
|
349 string like <quote><literal>2006-09-04 15:13:13
|
bos@559
|
350 -0700</literal></quote>.</para>
|
bos@559
|
351 </listitem>
|
bos@584
|
352 <listitem><para id="x_5ae"><literal
|
bos@559
|
353 role="template-filter">obfuscate</literal>: Any text, but
|
bos@559
|
354 most useful for the <literal
|
bos@559
|
355 role="template-keyword">author</literal> keyword. Yield
|
bos@559
|
356 the input text rendered as a sequence of XML entities. This
|
bos@559
|
357 helps to defeat some particularly stupid screen-scraping
|
bos@559
|
358 email harvesting spambots.</para>
|
bos@559
|
359 </listitem>
|
bos@584
|
360 <listitem><para id="x_5af"><literal
|
bos@559
|
361 role="template-kw-filt-author">person</literal>: Any text,
|
bos@559
|
362 but most useful for the <literal
|
bos@559
|
363 role="template-keyword">author</literal> keyword. Yield
|
bos@559
|
364 the text before an email address. For example,
|
bos@559
|
365 <quote><literal>Bryan O'Sullivan
|
bos@559
|
366 <bos@serpentine.com></literal></quote> becomes
|
bos@559
|
367 <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
|
bos@559
|
368 </listitem>
|
bos@584
|
369 <listitem><para id="x_5b0"><literal
|
bos@559
|
370 role="template-kw-filt-date">rfc822date</literal>:
|
bos@559
|
371 <literal role="template-keyword">date</literal> keyword.
|
bos@559
|
372 Render a date using the same format used in email headers.
|
bos@559
|
373 Yields a string like <quote><literal>Mon, 04 Sep 2006
|
bos@559
|
374 15:13:13 -0700</literal></quote>.</para>
|
bos@559
|
375 </listitem>
|
bos@584
|
376 <listitem><para id="x_5b1"><literal
|
bos@559
|
377 role="template-kw-filt-node">short</literal>: Changeset
|
bos@559
|
378 hash. Yield the short form of a changeset hash, i.e. a
|
bos@559
|
379 12-character hexadecimal string.</para>
|
bos@559
|
380 </listitem>
|
bos@584
|
381 <listitem><para id="x_5b2"><literal
|
bos@559
|
382 role="template-kw-filt-date">shortdate</literal>: <literal
|
bos@559
|
383 role="template-keyword">date</literal> keyword. Render
|
bos@559
|
384 the year, month, and day of the date. Yields a string like
|
bos@559
|
385 <quote><literal>2006-09-04</literal></quote>.</para>
|
bos@559
|
386 </listitem>
|
bos@584
|
387 <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>:
|
bos@559
|
388 Any text. Strip all leading and trailing whitespace from
|
bos@559
|
389 the string.</para>
|
bos@559
|
390 </listitem>
|
bos@584
|
391 <listitem><para id="x_5b4"><literal
|
bos@559
|
392 role="template-filter">tabindent</literal>: Any text.
|
bos@559
|
393 Yield the text, with every line except the first starting
|
bos@559
|
394 with a tab character.</para>
|
bos@559
|
395 </listitem>
|
bos@584
|
396 <listitem><para id="x_5b5"><literal
|
bos@559
|
397 role="template-filter">urlescape</literal>: Any text.
|
bos@559
|
398 Escape all characters that are considered
|
bos@559
|
399 <quote>special</quote> by URL parsers. For example,
|
bos@559
|
400 <literal>foo bar</literal> becomes
|
bos@559
|
401 <literal>foo%20bar</literal>.</para>
|
bos@559
|
402 </listitem>
|
bos@584
|
403 <listitem><para id="x_5b6"><literal
|
bos@559
|
404 role="template-kw-filt-author">user</literal>: Any text,
|
bos@559
|
405 but most useful for the <literal
|
bos@559
|
406 role="template-keyword">author</literal> keyword. Return
|
bos@559
|
407 the <quote>user</quote> portion of an email address. For
|
bos@559
|
408 example, <quote><literal>Bryan O'Sullivan
|
bos@559
|
409 <bos@serpentine.com></literal></quote> becomes
|
bos@559
|
410 <quote><literal>bos</literal></quote>.</para>
|
bos@559
|
411 </listitem></itemizedlist>
|
bos@559
|
412
|
bos@682
|
413 &interaction.template.simple.manyfilters;
|
bos@559
|
414
|
bos@559
|
415 <note>
|
bos@584
|
416 <para id="x_5b7"> If you try to apply a filter to a piece of data that it
|
bos@559
|
417 cannot process, Mercurial will fail and print a Python
|
bos@559
|
418 exception. For example, trying to run the output of the
|
bos@559
|
419 <literal role="template-keyword">desc</literal> keyword into
|
bos@559
|
420 the <literal role="template-kw-filt-date">isodate</literal>
|
bos@559
|
421 filter is not a good idea.</para>
|
bos@559
|
422 </note>
|
bos@559
|
423
|
bos@559
|
424 <sect2>
|
bos@559
|
425 <title>Combining filters</title>
|
bos@559
|
426
|
bos@584
|
427 <para id="x_5b8">It is easy to combine filters to yield output in the form
|
bos@559
|
428 you would like. The following chain of filters tidies up a
|
bos@559
|
429 description, then makes sure that it fits cleanly into 68
|
bos@559
|
430 columns, then indents it by a further 8 characters (at least
|
bos@559
|
431 on Unix-like systems, where a tab is conventionally 8
|
bos@559
|
432 characters wide).</para>
|
bos@559
|
433
|
bos@567
|
434 &interaction.template.simple.combine;
|
bos@559
|
435
|
bos@584
|
436 <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a
|
bos@559
|
437 tab character) in the template to force the first line to be
|
bos@559
|
438 indented; this is necessary since <literal
|
bos@559
|
439 role="template-keyword">tabindent</literal> indents all
|
bos@559
|
440 lines <emphasis>except</emphasis> the first.</para>
|
bos@559
|
441
|
bos@584
|
442 <para id="x_5ba">Keep in mind that the order of filters in a chain is
|
bos@559
|
443 significant. The first filter is applied to the result of the
|
bos@559
|
444 keyword; the second to the result of the first filter; and so
|
bos@559
|
445 on. For example, using <literal>fill68|tabindent</literal>
|
bos@559
|
446 gives very different results from
|
bos@559
|
447 <literal>tabindent|fill68</literal>.</para>
|
bos@559
|
448 </sect2>
|
bos@559
|
449 </sect1>
|
bos@682
|
450
|
bos@559
|
451 <sect1>
|
bos@559
|
452 <title>From templates to styles</title>
|
bos@559
|
453
|
bos@584
|
454 <para id="x_5bb">A command line template provides a quick and simple way to
|
bos@559
|
455 format some output. Templates can become verbose, though, and
|
bos@559
|
456 it's useful to be able to give a template a name. A style file
|
bos@559
|
457 is a template with a name, stored in a file.</para>
|
bos@559
|
458
|
bos@584
|
459 <para id="x_5bc">More than that, using a style file unlocks the power of
|
bos@559
|
460 Mercurial's templating engine in ways that are not possible
|
bos@559
|
461 using the command line <option
|
bos@559
|
462 role="hg-opt-log">--template</option> option.</para>
|
bos@559
|
463
|
bos@559
|
464 <sect2>
|
bos@559
|
465 <title>The simplest of style files</title>
|
bos@559
|
466
|
bos@584
|
467 <para id="x_5bd">Our simple style file contains just one line:</para>
|
bos@559
|
468
|
bos@567
|
469 &interaction.template.simple.rev;
|
bos@559
|
470
|
bos@584
|
471 <para id="x_5be">This tells Mercurial, <quote>if you're printing a
|
bos@559
|
472 changeset, use the text on the right as the
|
bos@559
|
473 template</quote>.</para>
|
bos@559
|
474
|
bos@559
|
475 </sect2>
|
bos@559
|
476 <sect2>
|
bos@559
|
477 <title>Style file syntax</title>
|
bos@559
|
478
|
bos@584
|
479 <para id="x_5bf">The syntax rules for a style file are simple.</para>
|
bos@559
|
480
|
bos@559
|
481 <itemizedlist>
|
bos@584
|
482 <listitem><para id="x_5c0">The file is processed one line at a
|
bos@559
|
483 time.</para>
|
bos@559
|
484 </listitem>
|
bos@584
|
485 <listitem><para id="x_5c1">Leading and trailing white space are
|
bos@559
|
486 ignored.</para>
|
bos@559
|
487 </listitem>
|
bos@584
|
488 <listitem><para id="x_5c2">Empty lines are skipped.</para>
|
bos@584
|
489 </listitem>
|
bos@584
|
490 <listitem><para id="x_5c3">If a line starts with either of the characters
|
bos@559
|
491 <quote><literal>#</literal></quote> or
|
bos@559
|
492 <quote><literal>;</literal></quote>, the entire line is
|
bos@559
|
493 treated as a comment, and skipped as if empty.</para>
|
bos@559
|
494 </listitem>
|
bos@584
|
495 <listitem><para id="x_5c4">A line starts with a keyword. This must start
|
bos@559
|
496 with an alphabetic character or underscore, and can
|
bos@559
|
497 subsequently contain any alphanumeric character or
|
bos@559
|
498 underscore. (In regexp notation, a keyword must match
|
bos@559
|
499 <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
|
bos@559
|
500 </listitem>
|
bos@584
|
501 <listitem><para id="x_5c5">The next element must be an
|
bos@559
|
502 <quote><literal>=</literal></quote> character, which can
|
bos@559
|
503 be preceded or followed by an arbitrary amount of white
|
bos@559
|
504 space.</para>
|
bos@559
|
505 </listitem>
|
bos@584
|
506 <listitem><para id="x_5c6">If the rest of the line starts and ends with
|
bos@559
|
507 matching quote characters (either single or double quote),
|
bos@559
|
508 it is treated as a template body.</para>
|
bos@559
|
509 </listitem>
|
bos@584
|
510 <listitem><para id="x_5c7">If the rest of the line <emphasis>does
|
bos@559
|
511 not</emphasis> start with a quote character, it is
|
bos@559
|
512 treated as the name of a file; the contents of this file
|
bos@559
|
513 will be read and used as a template body.</para>
|
bos@559
|
514 </listitem></itemizedlist>
|
bos@559
|
515 </sect2>
|
bos@559
|
516 </sect1>
|
bos@682
|
517
|
bos@559
|
518 <sect1>
|
bos@559
|
519 <title>Style files by example</title>
|
bos@559
|
520
|
bos@584
|
521 <para id="x_5c8">To illustrate how to write a style file, we will construct a
|
bos@559
|
522 few by example. Rather than provide a complete style file and
|
bos@559
|
523 walk through it, we'll mirror the usual process of developing a
|
bos@559
|
524 style file by starting with something very simple, and walking
|
bos@559
|
525 through a series of successively more complete examples.</para>
|
bos@559
|
526
|
bos@559
|
527 <sect2>
|
bos@559
|
528 <title>Identifying mistakes in style files</title>
|
bos@559
|
529
|
bos@584
|
530 <para id="x_5c9">If Mercurial encounters a problem in a style file you are
|
bos@559
|
531 working on, it prints a terse error message that, once you
|
bos@559
|
532 figure out what it means, is actually quite useful.</para>
|
bos@559
|
533
|
bos@567
|
534 &interaction.template.svnstyle.syntax.input;
|
bos@559
|
535
|
bos@584
|
536 <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to
|
bos@559
|
537 define a <literal>changeset</literal> keyword, but forgets to
|
bos@559
|
538 give any content for it. When instructed to use this style
|
bos@559
|
539 file, Mercurial promptly complains.</para>
|
bos@559
|
540
|
bos@567
|
541 &interaction.template.svnstyle.syntax.error;
|
bos@559
|
542
|
bos@584
|
543 <para id="x_5cb">This error message looks intimidating, but it is not too
|
bos@559
|
544 hard to follow.</para>
|
bos@559
|
545
|
bos@559
|
546 <itemizedlist>
|
bos@584
|
547 <listitem><para id="x_5cc">The first component is simply Mercurial's way
|
bos@559
|
548 of saying <quote>I am giving up</quote>.</para>
|
bos@580
|
549 <programlisting>___abort___: broken.style:1: parse error</programlisting>
|
bos@559
|
550 </listitem>
|
bos@584
|
551 <listitem><para id="x_5cd">Next comes the name of the style file that
|
bos@559
|
552 contains the error.</para>
|
bos@580
|
553 <programlisting>abort: ___broken.style___:1: parse error</programlisting>
|
bos@559
|
554 </listitem>
|
bos@584
|
555 <listitem><para id="x_5ce">Following the file name is the line number
|
bos@559
|
556 where the error was encountered.</para>
|
bos@580
|
557 <programlisting>abort: broken.style:___1___: parse error</programlisting>
|
bos@559
|
558 </listitem>
|
bos@584
|
559 <listitem><para id="x_5cf">Finally, a description of what went
|
bos@559
|
560 wrong.</para>
|
bos@580
|
561 <programlisting>abort: broken.style:1: ___parse error___</programlisting>
|
bos@559
|
562 </listitem>
|
bos@584
|
563 <listitem><para id="x_5d0">The description of the problem is not always
|
bos@559
|
564 clear (as in this case), but even when it is cryptic, it
|
bos@559
|
565 is almost always trivial to visually inspect the offending
|
bos@559
|
566 line in the style file and see what is wrong.</para>
|
bos@559
|
567 </listitem></itemizedlist>
|
bos@559
|
568 </sect2>
|
bos@682
|
569
|
bos@559
|
570 <sect2>
|
bos@559
|
571 <title>Uniquely identifying a repository</title>
|
bos@559
|
572
|
bos@584
|
573 <para id="x_5d1">If you would like to be able to identify a Mercurial
|
bos@559
|
574 repository <quote>fairly uniquely</quote> using a short string
|
bos@559
|
575 as an identifier, you can use the first revision in the
|
bos@567
|
576 repository.</para>
|
bos@567
|
577
|
bos@567
|
578 &interaction.template.svnstyle.id;
|
bos@567
|
579
|
bos@584
|
580 <para id="x_5d2">This is not guaranteed to be unique, but it is
|
bos@567
|
581 nevertheless useful in many cases.</para>
|
bos@559
|
582 <itemizedlist>
|
bos@584
|
583 <listitem><para id="x_5d3">It will not work in a completely empty
|
bos@559
|
584 repository, because such a repository does not have a
|
bos@559
|
585 revision zero.</para>
|
bos@559
|
586 </listitem>
|
bos@584
|
587 <listitem><para id="x_5d4">Neither will it work in the (extremely rare)
|
bos@559
|
588 case where a repository is a merge of two or more formerly
|
bos@559
|
589 independent repositories, and you still have those
|
bos@559
|
590 repositories around.</para>
|
bos@559
|
591 </listitem></itemizedlist>
|
bos@584
|
592 <para id="x_5d5">Here are some uses to which you could put this
|
bos@559
|
593 identifier:</para>
|
bos@559
|
594 <itemizedlist>
|
bos@584
|
595 <listitem><para id="x_5d6">As a key into a table for a database that
|
bos@559
|
596 manages repositories on a server.</para>
|
bos@559
|
597 </listitem>
|
bos@584
|
598 <listitem><para id="x_5d7">As half of a {<emphasis>repository
|
bos@559
|
599 ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
|
bos@559
|
600 Save this information away when you run an automated build
|
bos@559
|
601 or other activity, so that you can <quote>replay</quote>
|
bos@559
|
602 the build later if necessary.</para>
|
bos@559
|
603 </listitem></itemizedlist>
|
bos@559
|
604 </sect2>
|
bos@682
|
605
|
bos@559
|
606 <sect2>
|
bos@559
|
607 <title>Mimicking Subversion's output</title>
|
bos@559
|
608
|
bos@584
|
609 <para id="x_5d8">Let's try to emulate the default output format used by
|
bos@567
|
610 another revision control tool, Subversion.</para>
|
bos@567
|
611
|
bos@567
|
612 &interaction.template.svnstyle.short;
|
bos@559
|
613
|
bos@584
|
614 <para id="x_5d9">Since Subversion's output style is fairly simple, it is
|
bos@559
|
615 easy to copy-and-paste a hunk of its output into a file, and
|
bos@559
|
616 replace the text produced above by Subversion with the
|
bos@567
|
617 template values we'd like to see expanded.</para>
|
bos@567
|
618
|
bos@567
|
619 &interaction.template.svnstyle.template;
|
bos@559
|
620
|
bos@584
|
621 <para id="x_5da">There are a few small ways in which this template deviates
|
bos@559
|
622 from the output produced by Subversion.</para>
|
bos@559
|
623 <itemizedlist>
|
bos@584
|
624 <listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
|
ori@561
|
625 date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
|
bos@559
|
626 example output above) in parentheses. Mercurial's
|
bos@559
|
627 templating engine does not provide a way to display a date
|
bos@559
|
628 in this format without also printing the time and time
|
bos@559
|
629 zone.</para>
|
bos@559
|
630 </listitem>
|
bos@584
|
631 <listitem><para id="x_5dc">We emulate Subversion's printing of
|
bos@559
|
632 <quote>separator</quote> lines full of
|
bos@559
|
633 <quote><literal>-</literal></quote> characters by ending
|
bos@559
|
634 the template with such a line. We use the templating
|
bos@559
|
635 engine's <literal role="template-keyword">header</literal>
|
bos@559
|
636 keyword to print a separator line as the first line of
|
bos@559
|
637 output (see below), thus achieving similar output to
|
bos@559
|
638 Subversion.</para>
|
bos@559
|
639 </listitem>
|
bos@584
|
640 <listitem><para id="x_5dd">Subversion's output includes a count in the
|
bos@559
|
641 header of the number of lines in the commit message. We
|
bos@559
|
642 cannot replicate this in Mercurial; the templating engine
|
bos@559
|
643 does not currently provide a filter that counts the number
|
bos@559
|
644 of lines the template generates.</para>
|
bos@559
|
645 </listitem></itemizedlist>
|
bos@584
|
646 <para id="x_5de">It took me no more than a minute or two of work to replace
|
bos@559
|
647 literal text from an example of Subversion's output with some
|
bos@559
|
648 keywords and filters to give the template above. The style
|
bos@567
|
649 file simply refers to the template.</para>
|
bos@567
|
650
|
bos@567
|
651 &interaction.template.svnstyle.style;
|
bos@559
|
652
|
bos@584
|
653 <para id="x_5df">We could have included the text of the template file
|
bos@559
|
654 directly in the style file by enclosing it in quotes and
|
bos@559
|
655 replacing the newlines with
|
bos@559
|
656 <quote><literal>\n</literal></quote> sequences, but it would
|
bos@559
|
657 have made the style file too difficult to read. Readability
|
bos@559
|
658 is a good guide when you're trying to decide whether some text
|
bos@559
|
659 belongs in a style file, or in a template file that the style
|
bos@559
|
660 file points to. If the style file will look too big or
|
bos@559
|
661 cluttered if you insert a literal piece of text, drop it into
|
bos@559
|
662 a template instead.</para>
|
bos@559
|
663 </sect2>
|
bos@559
|
664 </sect1>
|
bos@559
|
665 </chapter>
|
bos@559
|
666
|
bos@559
|
667 <!--
|
bos@559
|
668 local variables:
|
bos@559
|
669 sgml-parent-document: ("00book.xml" "book" "chapter")
|
bos@559
|
670 end:
|
bos@559
|
671 -->
|