hgbook

annotate fr/ch11-template.xml @ 982:a9c3a727f253

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