hgbook

annotate en/ch11-template.xml @ 1047:eb90573d2f76

refine 1.6.2
author Zhaoping Sun <zhaopingsun@gmail.com>
date Mon Nov 09 23:13:00 2009 -0500 (2009-11-09)
parents 9e33729cafae
children
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@696 5 <title>Customizing 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@696 10 command, or to customize 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@696 74 important commands that need customizable 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@696 77 </sect1>
bos@696 78
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@696 189 </listitem>
bos@696 190 </itemizedlist>
bos@559 191
bos@584 192 <para id="x_595">A few simple experiments will show us what to expect when we
bos@559 193 use these keywords; you can see the results below.</para>
bos@559 194
bos@696 195 &interaction.template.simple.keywords;
bos@559 196
bos@584 197 <para id="x_596">As we noted above, the date keyword does not produce
bos@559 198 human-readable output, so we must treat it specially. This
bos@559 199 involves using a <emphasis>filter</emphasis>, about which more
bos@592 200 in <xref linkend="sec:template:filter"/>.</para>
bos@559 201
bos@567 202 &interaction.template.simple.datekeyword;
bos@682 203 </sect1>
bos@682 204
bos@559 205 <sect1 id="sec:template:escape">
bos@559 206 <title>Escape sequences</title>
bos@559 207
bos@584 208 <para id="x_597">Mercurial's templating engine recognises the most commonly
bos@559 209 used escape sequences in strings. When it sees a backslash
bos@559 210 (<quote><literal>\</literal></quote>) character, it looks at the
bos@559 211 following character and substitutes the two characters with a
bos@559 212 single replacement, as described below.</para>
bos@559 213
bos@559 214 <itemizedlist>
bos@584 215 <listitem><para id="x_598"><literal>\</literal>:
bos@559 216 Backslash, <quote><literal>\</literal></quote>, ASCII
bos@559 217 134.</para>
bos@559 218 </listitem>
bos@584 219 <listitem><para id="x_599"><literal>\n</literal>: Newline,
bos@559 220 ASCII 12.</para>
bos@559 221 </listitem>
bos@584 222 <listitem><para id="x_59a"><literal>\r</literal>: Carriage
bos@559 223 return, ASCII 15.</para>
bos@559 224 </listitem>
bos@584 225 <listitem><para id="x_59b"><literal>\t</literal>: Tab, ASCII
bos@559 226 11.</para>
bos@559 227 </listitem>
bos@584 228 <listitem><para id="x_59c"><literal>\v</literal>: Vertical
bos@559 229 tab, ASCII 13.</para>
bos@559 230 </listitem>
bos@696 231 <listitem><para id="x_59d"><literal>\{</literal>: Open curly
bos@559 232 brace, <quote><literal>{</literal></quote>, ASCII
bos@559 233 173.</para>
bos@559 234 </listitem>
bos@696 235 <listitem><para id="x_59e"><literal>\}</literal>: Close curly
bos@559 236 brace, <quote><literal>}</literal></quote>, ASCII
bos@559 237 175.</para>
bos@559 238 </listitem></itemizedlist>
bos@559 239
bos@584 240 <para id="x_59f">As indicated above, if you want the expansion of a template
bos@559 241 to contain a literal <quote><literal>\</literal></quote>,
bos@559 242 <quote><literal>{</literal></quote>, or
bos@559 243 <quote><literal>{</literal></quote> character, you must escape
bos@559 244 it.</para>
bos@682 245 </sect1>
bos@682 246
bos@559 247 <sect1 id="sec:template:filter">
bos@559 248 <title>Filtering keywords to change their results</title>
bos@559 249
bos@584 250 <para id="x_5a0">Some of the results of template expansion are not
bos@559 251 immediately easy to use. Mercurial lets you specify an optional
bos@559 252 chain of <emphasis>filters</emphasis> to modify the result of
bos@559 253 expanding a keyword. You have already seen a common filter,
bos@559 254 <literal role="template-kw-filt-date">isodate</literal>, in
bos@559 255 action above, to make a date readable.</para>
bos@559 256
bos@584 257 <para id="x_5a1">Below is a list of the most commonly used filters that
bos@559 258 Mercurial supports. While some filters can be applied to any
bos@559 259 text, others can only be used in specific circumstances. The
bos@559 260 name of each filter is followed first by an indication of where
bos@559 261 it can be used, then a description of its effect.</para>
bos@559 262
bos@559 263 <itemizedlist>
bos@584 264 <listitem><para id="x_5a2"><literal
bos@559 265 role="template-filter">addbreaks</literal>: Any text. Add
bos@559 266 an XHTML <quote><literal>&lt;br/&gt;</literal></quote> tag
bos@559 267 before the end of every line except the last. For example,
bos@559 268 <quote><literal>foo\nbar</literal></quote> becomes
bos@559 269 <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.</para>
bos@559 270 </listitem>
bos@584 271 <listitem><para id="x_5a3"><literal
bos@559 272 role="template-kw-filt-date">age</literal>: <literal
bos@559 273 role="template-keyword">date</literal> keyword. Render
bos@559 274 the age of the date, relative to the current time. Yields a
bos@559 275 string like <quote><literal>10
bos@559 276 minutes</literal></quote>.</para>
bos@559 277 </listitem>
bos@584 278 <listitem><para id="x_5a4"><literal
bos@559 279 role="template-filter">basename</literal>: Any text, but
bos@559 280 most useful for the <literal
bos@559 281 role="template-keyword">files</literal> keyword and its
bos@559 282 relatives. Treat the text as a path, and return the
bos@559 283 basename. For example,
bos@559 284 <quote><literal>foo/bar/baz</literal></quote> becomes
bos@559 285 <quote><literal>baz</literal></quote>.</para>
bos@559 286 </listitem>
bos@584 287 <listitem><para id="x_5a5"><literal
bos@559 288 role="template-kw-filt-date">date</literal>: <literal
bos@559 289 role="template-keyword">date</literal> keyword. Render a
bos@559 290 date in a similar format to the Unix <literal
bos@559 291 role="template-keyword">date</literal> command, but with
bos@559 292 timezone included. Yields a string like <quote><literal>Mon
bos@559 293 Sep 04 15:13:13 2006 -0700</literal></quote>.</para>
bos@559 294 </listitem>
bos@584 295 <listitem><para id="x_5a6"><literal
bos@559 296 role="template-kw-filt-author">domain</literal>: Any text,
bos@559 297 but most useful for the <literal
bos@559 298 role="template-keyword">author</literal> keyword. Finds
bos@559 299 the first string that looks like an email address, and
bos@559 300 extract just the domain component. For example,
bos@559 301 <quote><literal>Bryan O'Sullivan
bos@559 302 &lt;bos@serpentine.com&gt;</literal></quote> becomes
bos@559 303 <quote><literal>serpentine.com</literal></quote>.</para>
bos@559 304 </listitem>
bos@584 305 <listitem><para id="x_5a7"><literal
bos@559 306 role="template-kw-filt-author">email</literal>: Any text,
bos@559 307 but most useful for the <literal
bos@559 308 role="template-keyword">author</literal> keyword. Extract
bos@559 309 the first string that looks like an email address. For
bos@559 310 example, <quote><literal>Bryan O'Sullivan
bos@559 311 &lt;bos@serpentine.com&gt;</literal></quote> becomes
bos@559 312 <quote><literal>bos@serpentine.com</literal></quote>.</para>
bos@559 313 </listitem>
bos@584 314 <listitem><para id="x_5a8"><literal
bos@559 315 role="template-filter">escape</literal>: Any text.
bos@559 316 Replace the special XML/XHTML characters
bos@559 317 <quote><literal>&amp;</literal></quote>,
bos@559 318 <quote><literal>&lt;</literal></quote> and
bos@559 319 <quote><literal>&gt;</literal></quote> with XML
bos@559 320 entities.</para>
bos@559 321 </listitem>
bos@584 322 <listitem><para id="x_5a9"><literal
bos@559 323 role="template-filter">fill68</literal>: Any text. Wrap
bos@559 324 the text to fit in 68 columns. This is useful before you
bos@559 325 pass text through the <literal
bos@559 326 role="template-filter">tabindent</literal> filter, and
bos@559 327 still want it to fit in an 80-column fixed-font
bos@559 328 window.</para>
bos@559 329 </listitem>
bos@584 330 <listitem><para id="x_5aa"><literal
bos@559 331 role="template-filter">fill76</literal>: Any text. Wrap
bos@559 332 the text to fit in 76 columns.</para>
bos@559 333 </listitem>
bos@584 334 <listitem><para id="x_5ab"><literal
bos@559 335 role="template-filter">firstline</literal>: Any text.
bos@559 336 Yield the first line of text, without any trailing
bos@559 337 newlines.</para>
bos@559 338 </listitem>
bos@584 339 <listitem><para id="x_5ac"><literal
bos@559 340 role="template-kw-filt-date">hgdate</literal>: <literal
bos@559 341 role="template-keyword">date</literal> keyword. Render
bos@559 342 the date as a pair of readable numbers. Yields a string
bos@559 343 like <quote><literal>1157407993
bos@559 344 25200</literal></quote>.</para>
bos@559 345 </listitem>
bos@584 346 <listitem><para id="x_5ad"><literal
bos@559 347 role="template-kw-filt-date">isodate</literal>: <literal
bos@559 348 role="template-keyword">date</literal> keyword. Render
bos@559 349 the date as a text string in ISO 8601 format. Yields a
bos@559 350 string like <quote><literal>2006-09-04 15:13:13
bos@559 351 -0700</literal></quote>.</para>
bos@559 352 </listitem>
bos@584 353 <listitem><para id="x_5ae"><literal
bos@559 354 role="template-filter">obfuscate</literal>: Any text, but
bos@559 355 most useful for the <literal
bos@559 356 role="template-keyword">author</literal> keyword. Yield
bos@559 357 the input text rendered as a sequence of XML entities. This
bos@559 358 helps to defeat some particularly stupid screen-scraping
bos@559 359 email harvesting spambots.</para>
bos@559 360 </listitem>
bos@584 361 <listitem><para id="x_5af"><literal
bos@559 362 role="template-kw-filt-author">person</literal>: Any text,
bos@559 363 but most useful for the <literal
bos@559 364 role="template-keyword">author</literal> keyword. Yield
bos@559 365 the text before an email address. For example,
bos@559 366 <quote><literal>Bryan O'Sullivan
bos@559 367 &lt;bos@serpentine.com&gt;</literal></quote> becomes
bos@559 368 <quote><literal>Bryan O'Sullivan</literal></quote>.</para>
bos@559 369 </listitem>
bos@584 370 <listitem><para id="x_5b0"><literal
bos@559 371 role="template-kw-filt-date">rfc822date</literal>:
bos@559 372 <literal role="template-keyword">date</literal> keyword.
bos@559 373 Render a date using the same format used in email headers.
bos@559 374 Yields a string like <quote><literal>Mon, 04 Sep 2006
bos@559 375 15:13:13 -0700</literal></quote>.</para>
bos@559 376 </listitem>
bos@584 377 <listitem><para id="x_5b1"><literal
bos@559 378 role="template-kw-filt-node">short</literal>: Changeset
bos@559 379 hash. Yield the short form of a changeset hash, i.e. a
bos@559 380 12-character hexadecimal string.</para>
bos@559 381 </listitem>
bos@584 382 <listitem><para id="x_5b2"><literal
bos@559 383 role="template-kw-filt-date">shortdate</literal>: <literal
bos@559 384 role="template-keyword">date</literal> keyword. Render
bos@559 385 the year, month, and day of the date. Yields a string like
bos@559 386 <quote><literal>2006-09-04</literal></quote>.</para>
bos@559 387 </listitem>
bos@584 388 <listitem><para id="x_5b3"><literal role="template-filter">strip</literal>:
bos@559 389 Any text. Strip all leading and trailing whitespace from
bos@559 390 the string.</para>
bos@559 391 </listitem>
bos@584 392 <listitem><para id="x_5b4"><literal
bos@559 393 role="template-filter">tabindent</literal>: Any text.
bos@559 394 Yield the text, with every line except the first starting
bos@559 395 with a tab character.</para>
bos@559 396 </listitem>
bos@584 397 <listitem><para id="x_5b5"><literal
bos@559 398 role="template-filter">urlescape</literal>: Any text.
bos@559 399 Escape all characters that are considered
bos@559 400 <quote>special</quote> by URL parsers. For example,
bos@559 401 <literal>foo bar</literal> becomes
bos@559 402 <literal>foo%20bar</literal>.</para>
bos@559 403 </listitem>
bos@584 404 <listitem><para id="x_5b6"><literal
bos@559 405 role="template-kw-filt-author">user</literal>: Any text,
bos@559 406 but most useful for the <literal
bos@559 407 role="template-keyword">author</literal> keyword. Return
bos@559 408 the <quote>user</quote> portion of an email address. For
bos@559 409 example, <quote><literal>Bryan O'Sullivan
bos@559 410 &lt;bos@serpentine.com&gt;</literal></quote> becomes
bos@559 411 <quote><literal>bos</literal></quote>.</para>
bos@696 412 </listitem>
bos@696 413 </itemizedlist>
bos@559 414
bos@682 415 &interaction.template.simple.manyfilters;
bos@559 416
bos@559 417 <note>
bos@584 418 <para id="x_5b7"> If you try to apply a filter to a piece of data that it
bos@559 419 cannot process, Mercurial will fail and print a Python
bos@559 420 exception. For example, trying to run the output of the
bos@559 421 <literal role="template-keyword">desc</literal> keyword into
bos@559 422 the <literal role="template-kw-filt-date">isodate</literal>
bos@559 423 filter is not a good idea.</para>
bos@559 424 </note>
bos@559 425
bos@559 426 <sect2>
bos@559 427 <title>Combining filters</title>
bos@559 428
bos@584 429 <para id="x_5b8">It is easy to combine filters to yield output in the form
bos@559 430 you would like. The following chain of filters tidies up a
bos@559 431 description, then makes sure that it fits cleanly into 68
bos@559 432 columns, then indents it by a further 8 characters (at least
bos@559 433 on Unix-like systems, where a tab is conventionally 8
bos@559 434 characters wide).</para>
bos@559 435
bos@567 436 &interaction.template.simple.combine;
bos@559 437
bos@584 438 <para id="x_5b9">Note the use of <quote><literal>\t</literal></quote> (a
bos@559 439 tab character) in the template to force the first line to be
bos@559 440 indented; this is necessary since <literal
bos@559 441 role="template-keyword">tabindent</literal> indents all
bos@559 442 lines <emphasis>except</emphasis> the first.</para>
bos@559 443
bos@584 444 <para id="x_5ba">Keep in mind that the order of filters in a chain is
bos@559 445 significant. The first filter is applied to the result of the
bos@559 446 keyword; the second to the result of the first filter; and so
bos@559 447 on. For example, using <literal>fill68|tabindent</literal>
bos@559 448 gives very different results from
bos@559 449 <literal>tabindent|fill68</literal>.</para>
bos@559 450 </sect2>
bos@559 451 </sect1>
bos@682 452
bos@559 453 <sect1>
bos@559 454 <title>From templates to styles</title>
bos@559 455
bos@584 456 <para id="x_5bb">A command line template provides a quick and simple way to
bos@559 457 format some output. Templates can become verbose, though, and
bos@559 458 it's useful to be able to give a template a name. A style file
bos@559 459 is a template with a name, stored in a file.</para>
bos@559 460
bos@584 461 <para id="x_5bc">More than that, using a style file unlocks the power of
bos@559 462 Mercurial's templating engine in ways that are not possible
bos@559 463 using the command line <option
bos@559 464 role="hg-opt-log">--template</option> option.</para>
bos@559 465
bos@559 466 <sect2>
bos@559 467 <title>The simplest of style files</title>
bos@559 468
bos@584 469 <para id="x_5bd">Our simple style file contains just one line:</para>
bos@559 470
bos@567 471 &interaction.template.simple.rev;
bos@559 472
bos@584 473 <para id="x_5be">This tells Mercurial, <quote>if you're printing a
bos@559 474 changeset, use the text on the right as the
bos@559 475 template</quote>.</para>
bos@696 476 </sect2>
bos@696 477
bos@559 478 <sect2>
bos@559 479 <title>Style file syntax</title>
bos@559 480
bos@584 481 <para id="x_5bf">The syntax rules for a style file are simple.</para>
bos@559 482
bos@559 483 <itemizedlist>
bos@584 484 <listitem><para id="x_5c0">The file is processed one line at a
bos@559 485 time.</para>
bos@559 486 </listitem>
bos@584 487 <listitem><para id="x_5c1">Leading and trailing white space are
bos@559 488 ignored.</para>
bos@559 489 </listitem>
bos@584 490 <listitem><para id="x_5c2">Empty lines are skipped.</para>
bos@584 491 </listitem>
bos@584 492 <listitem><para id="x_5c3">If a line starts with either of the characters
bos@559 493 <quote><literal>#</literal></quote> or
bos@559 494 <quote><literal>;</literal></quote>, the entire line is
bos@559 495 treated as a comment, and skipped as if empty.</para>
bos@559 496 </listitem>
bos@584 497 <listitem><para id="x_5c4">A line starts with a keyword. This must start
bos@559 498 with an alphabetic character or underscore, and can
bos@559 499 subsequently contain any alphanumeric character or
bos@559 500 underscore. (In regexp notation, a keyword must match
bos@559 501 <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para>
bos@559 502 </listitem>
bos@584 503 <listitem><para id="x_5c5">The next element must be an
bos@559 504 <quote><literal>=</literal></quote> character, which can
bos@559 505 be preceded or followed by an arbitrary amount of white
bos@559 506 space.</para>
bos@559 507 </listitem>
bos@584 508 <listitem><para id="x_5c6">If the rest of the line starts and ends with
bos@559 509 matching quote characters (either single or double quote),
bos@559 510 it is treated as a template body.</para>
bos@559 511 </listitem>
bos@584 512 <listitem><para id="x_5c7">If the rest of the line <emphasis>does
bos@559 513 not</emphasis> start with a quote character, it is
bos@559 514 treated as the name of a file; the contents of this file
bos@559 515 will be read and used as a template body.</para>
bos@559 516 </listitem></itemizedlist>
bos@559 517 </sect2>
bos@559 518 </sect1>
bos@682 519
bos@559 520 <sect1>
bos@559 521 <title>Style files by example</title>
bos@559 522
bos@584 523 <para id="x_5c8">To illustrate how to write a style file, we will construct a
bos@559 524 few by example. Rather than provide a complete style file and
bos@559 525 walk through it, we'll mirror the usual process of developing a
bos@559 526 style file by starting with something very simple, and walking
bos@559 527 through a series of successively more complete examples.</para>
bos@559 528
bos@559 529 <sect2>
bos@559 530 <title>Identifying mistakes in style files</title>
bos@559 531
bos@584 532 <para id="x_5c9">If Mercurial encounters a problem in a style file you are
bos@559 533 working on, it prints a terse error message that, once you
bos@559 534 figure out what it means, is actually quite useful.</para>
bos@559 535
bos@567 536 &interaction.template.svnstyle.syntax.input;
bos@559 537
bos@584 538 <para id="x_5ca">Notice that <filename>broken.style</filename> attempts to
bos@559 539 define a <literal>changeset</literal> keyword, but forgets to
bos@559 540 give any content for it. When instructed to use this style
bos@559 541 file, Mercurial promptly complains.</para>
bos@559 542
bos@567 543 &interaction.template.svnstyle.syntax.error;
bos@559 544
bos@584 545 <para id="x_5cb">This error message looks intimidating, but it is not too
bos@559 546 hard to follow.</para>
bos@559 547
bos@559 548 <itemizedlist>
bos@584 549 <listitem><para id="x_5cc">The first component is simply Mercurial's way
bos@559 550 of saying <quote>I am giving up</quote>.</para>
bos@580 551 <programlisting>___abort___: broken.style:1: parse error</programlisting>
bos@559 552 </listitem>
bos@584 553 <listitem><para id="x_5cd">Next comes the name of the style file that
bos@559 554 contains the error.</para>
bos@580 555 <programlisting>abort: ___broken.style___:1: parse error</programlisting>
bos@559 556 </listitem>
bos@584 557 <listitem><para id="x_5ce">Following the file name is the line number
bos@559 558 where the error was encountered.</para>
bos@580 559 <programlisting>abort: broken.style:___1___: parse error</programlisting>
bos@559 560 </listitem>
bos@584 561 <listitem><para id="x_5cf">Finally, a description of what went
bos@559 562 wrong.</para>
bos@580 563 <programlisting>abort: broken.style:1: ___parse error___</programlisting>
bos@559 564 </listitem>
bos@584 565 <listitem><para id="x_5d0">The description of the problem is not always
bos@559 566 clear (as in this case), but even when it is cryptic, it
bos@559 567 is almost always trivial to visually inspect the offending
bos@559 568 line in the style file and see what is wrong.</para>
bos@696 569 </listitem>
bos@696 570 </itemizedlist>
bos@559 571 </sect2>
bos@682 572
bos@559 573 <sect2>
bos@559 574 <title>Uniquely identifying a repository</title>
bos@559 575
bos@584 576 <para id="x_5d1">If you would like to be able to identify a Mercurial
bos@559 577 repository <quote>fairly uniquely</quote> using a short string
bos@559 578 as an identifier, you can use the first revision in the
bos@567 579 repository.</para>
bos@567 580
bos@567 581 &interaction.template.svnstyle.id;
bos@567 582
bos@696 583 <para id="x_5d2">This is likely to be unique, and so it is
bos@696 584 useful in many cases. There are a few caveats.</para>
bos@559 585 <itemizedlist>
bos@584 586 <listitem><para id="x_5d3">It will not work in a completely empty
bos@559 587 repository, because such a repository does not have a
bos@559 588 revision zero.</para>
bos@559 589 </listitem>
bos@584 590 <listitem><para id="x_5d4">Neither will it work in the (extremely rare)
bos@559 591 case where a repository is a merge of two or more formerly
bos@559 592 independent repositories, and you still have those
bos@559 593 repositories around.</para>
bos@559 594 </listitem></itemizedlist>
bos@584 595 <para id="x_5d5">Here are some uses to which you could put this
bos@559 596 identifier:</para>
bos@559 597 <itemizedlist>
bos@584 598 <listitem><para id="x_5d6">As a key into a table for a database that
bos@559 599 manages repositories on a server.</para>
bos@559 600 </listitem>
bos@584 601 <listitem><para id="x_5d7">As half of a {<emphasis>repository
bos@559 602 ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
bos@559 603 Save this information away when you run an automated build
bos@559 604 or other activity, so that you can <quote>replay</quote>
bos@559 605 the build later if necessary.</para>
bos@696 606 </listitem>
bos@696 607 </itemizedlist>
bos@696 608 </sect2>
bos@696 609
bos@696 610 <sect2>
bos@696 611 <title>Listing files on multiple lines</title>
bos@696 612
bos@696 613 <para id="x_714">Suppose we want to list the files changed by a changeset,
bos@696 614 one per line, with a little indentation before each file
bos@696 615 name.</para>
bos@696 616
bos@696 617 &interaction.ch10-multiline.go;
bos@559 618 </sect2>
bos@682 619
bos@559 620 <sect2>
bos@559 621 <title>Mimicking Subversion's output</title>
bos@559 622
bos@584 623 <para id="x_5d8">Let's try to emulate the default output format used by
bos@567 624 another revision control tool, Subversion.</para>
bos@567 625
bos@567 626 &interaction.template.svnstyle.short;
bos@559 627
bos@584 628 <para id="x_5d9">Since Subversion's output style is fairly simple, it is
bos@559 629 easy to copy-and-paste a hunk of its output into a file, and
bos@559 630 replace the text produced above by Subversion with the
bos@567 631 template values we'd like to see expanded.</para>
bos@567 632
bos@567 633 &interaction.template.svnstyle.template;
bos@559 634
bos@584 635 <para id="x_5da">There are a few small ways in which this template deviates
bos@559 636 from the output produced by Subversion.</para>
bos@559 637 <itemizedlist>
bos@584 638 <listitem><para id="x_5db">Subversion prints a <quote>readable</quote>
ori@561 639 date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the
bos@559 640 example output above) in parentheses. Mercurial's
bos@559 641 templating engine does not provide a way to display a date
bos@559 642 in this format without also printing the time and time
bos@559 643 zone.</para>
bos@559 644 </listitem>
bos@584 645 <listitem><para id="x_5dc">We emulate Subversion's printing of
bos@559 646 <quote>separator</quote> lines full of
bos@559 647 <quote><literal>-</literal></quote> characters by ending
bos@559 648 the template with such a line. We use the templating
bos@559 649 engine's <literal role="template-keyword">header</literal>
bos@559 650 keyword to print a separator line as the first line of
bos@559 651 output (see below), thus achieving similar output to
bos@559 652 Subversion.</para>
bos@559 653 </listitem>
bos@584 654 <listitem><para id="x_5dd">Subversion's output includes a count in the
bos@559 655 header of the number of lines in the commit message. We
bos@559 656 cannot replicate this in Mercurial; the templating engine
bos@559 657 does not currently provide a filter that counts the number
bos@559 658 of lines the template generates.</para>
bos@559 659 </listitem></itemizedlist>
bos@584 660 <para id="x_5de">It took me no more than a minute or two of work to replace
bos@559 661 literal text from an example of Subversion's output with some
bos@559 662 keywords and filters to give the template above. The style
bos@567 663 file simply refers to the template.</para>
bos@567 664
bos@567 665 &interaction.template.svnstyle.style;
bos@559 666
bos@584 667 <para id="x_5df">We could have included the text of the template file
bos@559 668 directly in the style file by enclosing it in quotes and
bos@559 669 replacing the newlines with
bos@559 670 <quote><literal>\n</literal></quote> sequences, but it would
bos@559 671 have made the style file too difficult to read. Readability
bos@559 672 is a good guide when you're trying to decide whether some text
bos@559 673 belongs in a style file, or in a template file that the style
bos@559 674 file points to. If the style file will look too big or
bos@559 675 cluttered if you insert a literal piece of text, drop it into
bos@559 676 a template instead.</para>
bos@559 677 </sect2>
bos@559 678 </sect1>
bos@559 679 </chapter>
bos@559 680
bos@559 681 <!--
bos@559 682 local variables:
bos@559 683 sgml-parent-document: ("00book.xml" "book" "chapter")
bos@559 684 end:
bos@559 685 -->