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