hgbook

diff fr/ch11-template.xml @ 977:719b03ea27c8

merge with Italian, and very (few) work on ch03
author Romain PELISSE <belaran@gmail.com>
date Fri Sep 04 16:33:46 2009 +0200 (2009-09-04)
parents
children 6f8c48362758
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/fr/ch11-template.xml	Fri Sep 04 16:33:46 2009 +0200
     1.3 @@ -0,0 +1,689 @@
     1.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
     1.5 +
     1.6 +<chapter>
     1.7 +<title>Customising the output of Mercurial</title>
     1.8 +<para>\label{chap:template}</para>
     1.9 +
    1.10 +<para>Mercurial provides a powerful mechanism to let you control how it
    1.11 +displays information.  The mechanism is based on templates.  You can
    1.12 +use templates to generate specific output for a single command, or to
    1.13 +customise the entire appearance of the built-in web interface.</para>
    1.14 +
    1.15 +<sect1>
    1.16 +<title>Using precanned output styles</title>
    1.17 +<para>\label{sec:style}</para>
    1.18 +
    1.19 +<para>Packaged with Mercurial are some output styles that you can use
    1.20 +immediately.  A style is simply a precanned template that someone
    1.21 +wrote and installed somewhere that Mercurial can find.</para>
    1.22 +
    1.23 +<para>Before we take a look at Mercurial's bundled styles, let's review its
    1.24 +normal output.</para>
    1.25 +
    1.26 +<para><!-- &interaction.template.simple.normal; --></para>
    1.27 +
    1.28 +<para>This is somewhat informative, but it takes up a lot of space&emdash;five
    1.29 +lines of output per changeset.  The <literal>compact</literal> style reduces
    1.30 +this to three lines, presented in a sparse manner.</para>
    1.31 +
    1.32 +<para><!-- &interaction.template.simple.compact; --></para>
    1.33 +
    1.34 +<para>The <literal>changelog</literal> style hints at the expressive power of
    1.35 +Mercurial's templating engine.  This style attempts to follow the GNU
    1.36 +Project's changelog guidelines<citation>web:changelog</citation>.
    1.37 +</para>
    1.38 +
    1.39 +<para><!-- &interaction.template.simple.changelog; -->
    1.40 +</para>
    1.41 +
    1.42 +<para>You will not be shocked to learn that Mercurial's default output style
    1.43 +is named <literal>default</literal>.
    1.44 +</para>
    1.45 +
    1.46 +<sect2>
    1.47 +<title>Setting a default style</title>
    1.48 +
    1.49 +<para>You can modify the output style that Mercurial will use for every
    1.50 +command by editing your <filename role="special"> /.hgrc</filename>\ file, naming the style you would
    1.51 +prefer to use.
    1.52 +</para>
    1.53 +
    1.54 +<programlisting>
    1.55 +<para>  [ui]
    1.56 +  style = compact
    1.57 +</para>
    1.58 +</programlisting>
    1.59 +
    1.60 +<para>If you write a style of your own, you can use it by either providing
    1.61 +the path to your style file, or copying your style file into a
    1.62 +location where Mercurial can find it (typically the <literal>templates</literal>
    1.63 +subdirectory of your Mercurial install directory).
    1.64 +</para>
    1.65 +
    1.66 +</sect2>
    1.67 +</sect1>
    1.68 +<sect1>
    1.69 +<title>Commands that support styles and templates</title>
    1.70 +
    1.71 +<para>All of Mercurial's <quote><literal>log</literal>-like</quote> commands let you use styles
    1.72 +and templates: <command role="hg-cmd">hg incoming</command>, <command role="hg-cmd">hg log</command>, <command role="hg-cmd">hg outgoing</command>, and
    1.73 +<command role="hg-cmd">hg tip</command>.
    1.74 +</para>
    1.75 +
    1.76 +<para>As I write this manual, these are so far the only commands that
    1.77 +support styles and templates.  Since these are the most important
    1.78 +commands that need customisable output, there has been little pressure
    1.79 +from the Mercurial user community to add style and template support to
    1.80 +other commands.
    1.81 +</para>
    1.82 +
    1.83 +</sect1>
    1.84 +<sect1>
    1.85 +<title>The basics of templating</title>
    1.86 +
    1.87 +<para>At its simplest, a Mercurial template is a piece of text.  Some of the
    1.88 +text never changes, while other parts are <emphasis>expanded</emphasis>, or replaced
    1.89 +with new text, when necessary.
    1.90 +</para>
    1.91 +
    1.92 +<para>Before we continue, let's look again at a simple example of
    1.93 +Mercurial's normal output.
    1.94 +</para>
    1.95 +
    1.96 +<para><!-- &interaction.template.simple.normal; -->
    1.97 +</para>
    1.98 +
    1.99 +<para>Now, let's run the same command, but using a template to change its
   1.100 +output.
   1.101 +</para>
   1.102 +
   1.103 +<para><!-- &interaction.template.simple.simplest; -->
   1.104 +</para>
   1.105 +
   1.106 +<para>The example above illustrates the simplest possible template; it's
   1.107 +just a piece of static text, printed once for each changeset.  The
   1.108 +<option role="hg-opt-log">--template</option> option to the <command role="hg-cmd">hg log</command> command tells
   1.109 +Mercurial to use the given text as the template when printing each
   1.110 +changeset.
   1.111 +</para>
   1.112 +
   1.113 +<para>Notice that the template string above ends with the text
   1.114 +<quote><literal>\n</literal></quote>.  This is an <emphasis>escape sequence</emphasis>, telling Mercurial
   1.115 +to print a newline at the end of each template item.  If you omit this
   1.116 +newline, Mercurial will run each piece of output together.  See
   1.117 +section <xref linkend="sec:template:escape"/> for more details of escape sequences.
   1.118 +</para>
   1.119 +
   1.120 +<para>A template that prints a fixed string of text all the time isn't very
   1.121 +useful; let's try something a bit more complex.
   1.122 +</para>
   1.123 +
   1.124 +<para><!-- &interaction.template.simple.simplesub; -->
   1.125 +</para>
   1.126 +
   1.127 +<para>As you can see, the string <quote><literal>{desc}</literal></quote> in the template has been
   1.128 +replaced in the output with the description of each changeset.  Every
   1.129 +time Mercurial finds text enclosed in curly braces (<quote><literal>{</literal></quote>
   1.130 +and <quote>\texttt{}}</quote>), it will try to replace the braces and text with
   1.131 +the expansion of whatever is inside.  To print a literal curly brace,
   1.132 +you must escape it, as described in section <xref linkend="sec:template:escape"/>.
   1.133 +</para>
   1.134 +
   1.135 +</sect1>
   1.136 +<sect1>
   1.137 +<title>Common template keywords</title>
   1.138 +<para>\label{sec:template:keyword}
   1.139 +</para>
   1.140 +
   1.141 +<para>You can start writing simple templates immediately using the keywords
   1.142 +below.
   1.143 +</para>
   1.144 +
   1.145 +<itemizedlist>
   1.146 +<listitem><para><literal role="template-keyword">author</literal>: String.  The unmodified author of the changeset.
   1.147 +</para>
   1.148 +</listitem>
   1.149 +<listitem><para><literal role="template-keyword">branches</literal>: String.  The name of the branch on which
   1.150 +  the changeset was committed.  Will be empty if the branch name was
   1.151 +  <literal>default</literal>.
   1.152 +</para>
   1.153 +</listitem>
   1.154 +<listitem><para><literal role="template-keyword">date</literal>: Date information.  The date when the changeset
   1.155 +  was committed.  This is <emphasis>not</emphasis> human-readable; you must pass it
   1.156 +  through a filter that will render it appropriately.  See
   1.157 +  section <xref linkend="sec:template:filter"/> for more information on filters.
   1.158 +  The date is expressed as a pair of numbers.  The first number is a
   1.159 +  Unix UTC timestamp (seconds since January 1, 1970); the second is
   1.160 +  the offset of the committer's timezone from UTC, in seconds.
   1.161 +</para>
   1.162 +</listitem>
   1.163 +<listitem><para><literal role="template-keyword">desc</literal>: String.  The text of the changeset description.
   1.164 +</para>
   1.165 +</listitem>
   1.166 +<listitem><para><literal role="template-keyword">files</literal>: List of strings.  All files modified, added, or
   1.167 +  removed by this changeset.
   1.168 +</para>
   1.169 +</listitem>
   1.170 +<listitem><para><literal role="template-keyword">file_adds</literal>: List of strings.  Files added by this
   1.171 +  changeset.
   1.172 +</para>
   1.173 +</listitem>
   1.174 +<listitem><para><literal role="template-keyword">file_dels</literal>: List of strings.  Files removed by this
   1.175 +  changeset.
   1.176 +</para>
   1.177 +</listitem>
   1.178 +<listitem><para><literal role="template-keyword">node</literal>: String.  The changeset identification hash, as a
   1.179 +  40-character hexadecimal string.
   1.180 +</para>
   1.181 +</listitem>
   1.182 +<listitem><para><literal role="template-keyword">parents</literal>: List of strings.  The parents of the
   1.183 +  changeset.
   1.184 +</para>
   1.185 +</listitem>
   1.186 +<listitem><para><literal role="template-keyword">rev</literal>: Integer.  The repository-local changeset revision
   1.187 +  number.
   1.188 +</para>
   1.189 +</listitem>
   1.190 +<listitem><para><literal role="template-keyword">tags</literal>: List of strings.  Any tags associated with the
   1.191 +  changeset.
   1.192 +</para>
   1.193 +</listitem></itemizedlist>
   1.194 +
   1.195 +<para>A few simple experiments will show us what to expect when we use these
   1.196 +keywords; you can see the results in
   1.197 +figure <xref linkend="fig:template:keywords"/>.
   1.198 +</para>
   1.199 +
   1.200 +<informalfigure>
   1.201 +<para>  <!-- &interaction.template.simple.keywords; -->
   1.202 +  <caption><para>Template keywords in use</para></caption>
   1.203 +  \label{fig:template:keywords}
   1.204 +</para>
   1.205 +</informalfigure>
   1.206 +
   1.207 +<para>As we noted above, the date keyword does not produce human-readable
   1.208 +output, so we must treat it specially.  This involves using a
   1.209 +<emphasis>filter</emphasis>, about which more in section <xref linkend="sec:template:filter"/>.
   1.210 +</para>
   1.211 +
   1.212 +<para><!-- &interaction.template.simple.datekeyword; -->
   1.213 +</para>
   1.214 +
   1.215 +</sect1>
   1.216 +<sect1>
   1.217 +<title>Escape sequences</title>
   1.218 +<para>\label{sec:template:escape}
   1.219 +</para>
   1.220 +
   1.221 +<para>Mercurial's templating engine recognises the most commonly used escape
   1.222 +sequences in strings.  When it sees a backslash (<quote><literal>\</literal></quote>)
   1.223 +character, it looks at the following character and substitutes the two
   1.224 +characters with a single replacement, as described below.
   1.225 +</para>
   1.226 +
   1.227 +<itemizedlist>
   1.228 +<listitem><para><literal>\textbackslash\textbackslash</literal>: Backslash, <quote><literal>\</literal></quote>,
   1.229 +  ASCII 134.
   1.230 +</para>
   1.231 +</listitem>
   1.232 +<listitem><para><literal>\textbackslash n</literal>: Newline, ASCII 12.
   1.233 +</para>
   1.234 +</listitem>
   1.235 +<listitem><para><literal>\textbackslash r</literal>: Carriage return, ASCII 15.
   1.236 +</para>
   1.237 +</listitem>
   1.238 +<listitem><para><literal>\textbackslash t</literal>: Tab, ASCII 11.
   1.239 +</para>
   1.240 +</listitem>
   1.241 +<listitem><para><literal>\textbackslash v</literal>: Vertical tab, ASCII 13.
   1.242 +</para>
   1.243 +</listitem>
   1.244 +<listitem><para><literal>\textbackslash {</literal>: Open curly brace, <quote><literal>{</literal></quote>, ASCII 173.
   1.245 +</para>
   1.246 +</listitem>
   1.247 +<listitem><para><literal>\textbackslash }</literal>: Close curly brace, <quote><literal>}</literal></quote>, ASCII 175.
   1.248 +</para>
   1.249 +</listitem></itemizedlist>
   1.250 +
   1.251 +<para>As indicated above, if you want the expansion of a template to contain
   1.252 +a literal <quote><literal>\</literal></quote>, <quote><literal>{</literal></quote>, or <quote><literal>{</literal></quote> character, you
   1.253 +must escape it.
   1.254 +</para>
   1.255 +
   1.256 +</sect1>
   1.257 +<sect1>
   1.258 +<title>Filtering keywords to change their results</title>
   1.259 +<para>\label{sec:template:filter}
   1.260 +</para>
   1.261 +
   1.262 +<para>Some of the results of template expansion are not immediately easy to
   1.263 +use.  Mercurial lets you specify an optional chain of <emphasis>filters</emphasis>
   1.264 +to modify the result of expanding a keyword.  You have already seen a
   1.265 +common filter, <literal role="template-kw-filt-date">isodate</literal>, in action above, to make a
   1.266 +date readable.
   1.267 +</para>
   1.268 +
   1.269 +<para>Below is a list of the most commonly used filters that Mercurial
   1.270 +supports.  While some filters can be applied to any text, others can
   1.271 +only be used in specific circumstances.  The name of each filter is
   1.272 +followed first by an indication of where it can be used, then a
   1.273 +description of its effect.
   1.274 +</para>
   1.275 +
   1.276 +<itemizedlist>
   1.277 +<listitem><para><literal role="template-filter">addbreaks</literal>: Any text. Add an XHTML <quote><literal>&lt;br/&gt;</literal></quote>
   1.278 +  tag before the end of every line except the last.  For example,
   1.279 +  <quote><literal>foo\nbar</literal></quote> becomes <quote><literal>foo&lt;br/&gt;\nbar</literal></quote>.
   1.280 +</para>
   1.281 +</listitem>
   1.282 +<listitem><para><literal role="template-kw-filt-date">age</literal>: <literal role="template-keyword">date</literal> keyword.  Render the
   1.283 +  age of the date, relative to the current time.  Yields a string like
   1.284 +  <quote><literal>10 minutes</literal></quote>.
   1.285 +</para>
   1.286 +</listitem>
   1.287 +<listitem><para><literal role="template-filter">basename</literal>: Any text, but most useful for the
   1.288 +  <literal role="template-keyword">files</literal> keyword and its relatives.  Treat the text as a
   1.289 +  path, and return the basename. For example, <quote><literal>foo/bar/baz</literal></quote>
   1.290 +  becomes <quote><literal>baz</literal></quote>.
   1.291 +</para>
   1.292 +</listitem>
   1.293 +<listitem><para><literal role="template-kw-filt-date">date</literal>: <literal role="template-keyword">date</literal> keyword.  Render a date
   1.294 +  in a similar format to the Unix <literal role="template-keyword">date</literal> command, but with
   1.295 +  timezone included.  Yields a string like
   1.296 +  <quote><literal>Mon Sep 04 15:13:13 2006 -0700</literal></quote>.
   1.297 +</para>
   1.298 +</listitem>
   1.299 +<listitem><para><literal role="template-kw-filt-author">domain</literal>: Any text, but most useful for the
   1.300 +  <literal role="template-keyword">author</literal> keyword.  Finds the first string that looks like
   1.301 +  an email address, and extract just the domain component.  For
   1.302 +  example, <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes
   1.303 +  <quote><literal>serpentine.com</literal></quote>.
   1.304 +</para>
   1.305 +</listitem>
   1.306 +<listitem><para><literal role="template-kw-filt-author">email</literal>: Any text, but most useful for the
   1.307 +  <literal role="template-keyword">author</literal> keyword.  Extract the first string that looks like
   1.308 +  an email address.  For example,
   1.309 +  <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes
   1.310 +  <quote><literal>bos@serpentine.com</literal></quote>.
   1.311 +</para>
   1.312 +</listitem>
   1.313 +<listitem><para><literal role="template-filter">escape</literal>: Any text.  Replace the special XML/XHTML
   1.314 +  characters <quote><literal>&amp;</literal></quote>, <quote><literal>&lt;</literal></quote> and <quote><literal>&gt;</literal></quote> with
   1.315 +  XML entities.
   1.316 +</para>
   1.317 +</listitem>
   1.318 +<listitem><para><literal role="template-filter">fill68</literal>: Any text.  Wrap the text to fit in 68
   1.319 +  columns.  This is useful before you pass text through the
   1.320 +  <literal role="template-filter">tabindent</literal> filter, and still want it to fit in an
   1.321 +  80-column fixed-font window.
   1.322 +</para>
   1.323 +</listitem>
   1.324 +<listitem><para><literal role="template-filter">fill76</literal>: Any text.  Wrap the text to fit in 76
   1.325 +  columns.
   1.326 +</para>
   1.327 +</listitem>
   1.328 +<listitem><para><literal role="template-filter">firstline</literal>: Any text.  Yield the first line of text,
   1.329 +  without any trailing newlines.
   1.330 +</para>
   1.331 +</listitem>
   1.332 +<listitem><para><literal role="template-kw-filt-date">hgdate</literal>: <literal role="template-keyword">date</literal> keyword.  Render the
   1.333 +  date as a pair of readable numbers.  Yields a string like
   1.334 +  <quote><literal>1157407993 25200</literal></quote>.
   1.335 +</para>
   1.336 +</listitem>
   1.337 +<listitem><para><literal role="template-kw-filt-date">isodate</literal>: <literal role="template-keyword">date</literal> keyword.  Render the
   1.338 +  date as a text string in ISO 8601 format.  Yields a string like
   1.339 +  <quote><literal>2006-09-04 15:13:13 -0700</literal></quote>.
   1.340 +</para>
   1.341 +</listitem>
   1.342 +<listitem><para><literal role="template-filter">obfuscate</literal>: Any text, but most useful for the
   1.343 +  <literal role="template-keyword">author</literal> keyword.  Yield the input text rendered as a
   1.344 +  sequence of XML entities.  This helps to defeat some particularly
   1.345 +  stupid screen-scraping email harvesting spambots.
   1.346 +</para>
   1.347 +</listitem>
   1.348 +<listitem><para><literal role="template-kw-filt-author">person</literal>: Any text, but most useful for the
   1.349 +  <literal role="template-keyword">author</literal> keyword.  Yield the text before an email address.
   1.350 +  For example, <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote>
   1.351 +  becomes <quote><literal>Bryan O'Sullivan</literal></quote>.
   1.352 +</para>
   1.353 +</listitem>
   1.354 +<listitem><para><literal role="template-kw-filt-date">rfc822date</literal>: <literal role="template-keyword">date</literal> keyword.  Render a
   1.355 +  date using the same format used in email headers.  Yields a string
   1.356 +  like <quote><literal>Mon, 04 Sep 2006 15:13:13 -0700</literal></quote>.
   1.357 +</para>
   1.358 +</listitem>
   1.359 +<listitem><para><literal role="template-kw-filt-node">short</literal>: Changeset hash.  Yield the short form
   1.360 +  of a changeset hash, i.e. a 12-character hexadecimal string.
   1.361 +</para>
   1.362 +</listitem>
   1.363 +<listitem><para><literal role="template-kw-filt-date">shortdate</literal>: <literal role="template-keyword">date</literal> keyword.  Render
   1.364 +  the year, month, and day of the date.  Yields a string like
   1.365 +  <quote><literal>2006-09-04</literal></quote>.
   1.366 +</para>
   1.367 +</listitem>
   1.368 +<listitem><para><literal role="template-filter">strip</literal>: Any text.  Strip all leading and trailing
   1.369 +  whitespace from the string.
   1.370 +</para>
   1.371 +</listitem>
   1.372 +<listitem><para><literal role="template-filter">tabindent</literal>: Any text.  Yield the text, with every line
   1.373 +  except the first starting with a tab character.
   1.374 +</para>
   1.375 +</listitem>
   1.376 +<listitem><para><literal role="template-filter">urlescape</literal>: Any text.  Escape all characters that are
   1.377 +  considered <quote>special</quote> by URL parsers.  For example, <literal>foo bar</literal>
   1.378 +  becomes <literal>foo%20bar</literal>.
   1.379 +</para>
   1.380 +</listitem>
   1.381 +<listitem><para><literal role="template-kw-filt-author">user</literal>: Any text, but most useful for the
   1.382 +  <literal role="template-keyword">author</literal> keyword.  Return the <quote>user</quote> portion of an email
   1.383 +  address.  For example,
   1.384 +  <quote><literal>Bryan O'Sullivan &lt;bos@serpentine.com&gt;</literal></quote> becomes
   1.385 +  <quote><literal>bos</literal></quote>.
   1.386 +</para>
   1.387 +</listitem></itemizedlist>
   1.388 +
   1.389 +<informalfigure>
   1.390 +<para>  <!-- &interaction.template.simple.manyfilters; -->
   1.391 +  <caption><para>Template filters in action</para></caption>
   1.392 +  \label{fig:template:filters}
   1.393 +</para>
   1.394 +</informalfigure>
   1.395 +
   1.396 +<note>
   1.397 +<para>  If you try to apply a filter to a piece of data that it cannot
   1.398 +  process, Mercurial will fail and print a Python exception.  For
   1.399 +  example, trying to run the output of the <literal role="template-keyword">desc</literal> keyword
   1.400 +  into the <literal role="template-kw-filt-date">isodate</literal> filter is not a good idea.
   1.401 +</para>
   1.402 +</note>
   1.403 +
   1.404 +<sect2>
   1.405 +<title>Combining filters</title>
   1.406 +
   1.407 +<para>It is easy to combine filters to yield output in the form you would
   1.408 +like.  The following chain of filters tidies up a description, then
   1.409 +makes sure that it fits cleanly into 68 columns, then indents it by a
   1.410 +further 8 characters (at least on Unix-like systems, where a tab is
   1.411 +conventionally 8 characters wide).
   1.412 +</para>
   1.413 +
   1.414 +<para><!-- &interaction.template.simple.combine; -->
   1.415 +</para>
   1.416 +
   1.417 +<para>Note the use of <quote><literal>\t</literal></quote> (a tab character) in the template to
   1.418 +force the first line to be indented; this is necessary since
   1.419 +<literal role="template-keyword">tabindent</literal> indents all lines <emphasis>except</emphasis> the first.
   1.420 +</para>
   1.421 +
   1.422 +<para>Keep in mind that the order of filters in a chain is significant.  The
   1.423 +first filter is applied to the result of the keyword; the second to
   1.424 +the result of the first filter; and so on.  For example, using
   1.425 +<literal>fill68|tabindent</literal> gives very different results from
   1.426 +<literal>tabindent|fill68</literal>.
   1.427 +</para>
   1.428 +
   1.429 +
   1.430 +</sect2>
   1.431 +</sect1>
   1.432 +<sect1>
   1.433 +<title>From templates to styles</title>
   1.434 +
   1.435 +<para>A command line template provides a quick and simple way to format some
   1.436 +output.  Templates can become verbose, though, and it's useful to be
   1.437 +able to give a template a name.  A style file is a template with a
   1.438 +name, stored in a file.
   1.439 +</para>
   1.440 +
   1.441 +<para>More than that, using a style file unlocks the power of Mercurial's
   1.442 +templating engine in ways that are not possible using the command line
   1.443 +<option role="hg-opt-log">--template</option> option.
   1.444 +</para>
   1.445 +
   1.446 +<sect2>
   1.447 +<title>The simplest of style files</title>
   1.448 +
   1.449 +<para>Our simple style file contains just one line:
   1.450 +</para>
   1.451 +
   1.452 +<para><!-- &interaction.template.simple.rev; -->
   1.453 +</para>
   1.454 +
   1.455 +<para>This tells Mercurial, <quote>if you're printing a changeset, use the text
   1.456 +on the right as the template</quote>.
   1.457 +</para>
   1.458 +
   1.459 +</sect2>
   1.460 +<sect2>
   1.461 +<title>Style file syntax</title>
   1.462 +
   1.463 +<para>The syntax rules for a style file are simple.
   1.464 +</para>
   1.465 +
   1.466 +<itemizedlist>
   1.467 +<listitem><para>The file is processed one line at a time.
   1.468 +</para>
   1.469 +</listitem>
   1.470 +</para>
   1.471 +</listitem>
   1.472 +<listitem><para>Leading and trailing white space are ignored.
   1.473 +</para>
   1.474 +</listitem>
   1.475 +</para>
   1.476 +</listitem>
   1.477 +<listitem><para>Empty lines are skipped.
   1.478 +</para>
   1.479 +</listitem>
   1.480 +</para>
   1.481 +</listitem>
   1.482 +<listitem><para>If a line starts with either of the characters <quote><literal>#</literal></quote> or
   1.483 +  <quote><literal>;</literal></quote>, the entire line is treated as a comment, and skipped
   1.484 +  as if empty.
   1.485 +</para>
   1.486 +</listitem>
   1.487 +</para>
   1.488 +</listitem>
   1.489 +<listitem><para>A line starts with a keyword.  This must start with an
   1.490 +  alphabetic character or underscore, and can subsequently contain any
   1.491 +  alphanumeric character or underscore.  (In regexp notation, a
   1.492 +  keyword must match <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)
   1.493 +</para>
   1.494 +</listitem>
   1.495 +</para>
   1.496 +</listitem>
   1.497 +<listitem><para>The next element must be an <quote><literal>=</literal></quote> character, which can
   1.498 +  be preceded or followed by an arbitrary amount of white space.
   1.499 +</para>
   1.500 +</listitem>
   1.501 +</para>
   1.502 +</listitem>
   1.503 +<listitem><para>If the rest of the line starts and ends with matching quote
   1.504 +  characters (either single or double quote), it is treated as a
   1.505 +  template body.
   1.506 +</para>
   1.507 +</listitem>
   1.508 +</para>
   1.509 +</listitem>
   1.510 +<listitem><para>If the rest of the line <emphasis>does not</emphasis> start with a quote
   1.511 +  character, it is treated as the name of a file; the contents of this
   1.512 +  file will be read and used as a template body.
   1.513 +</para>
   1.514 +</listitem></itemizedlist>
   1.515 +
   1.516 +</sect2>
   1.517 +</sect1>
   1.518 +<sect1>
   1.519 +<title>Style files by example</title>
   1.520 +
   1.521 +<para>To illustrate how to write a style file, we will construct a few by
   1.522 +example.  Rather than provide a complete style file and walk through
   1.523 +it, we'll mirror the usual process of developing a style file by
   1.524 +starting with something very simple, and walking through a series of
   1.525 +successively more complete examples.
   1.526 +</para>
   1.527 +
   1.528 +<sect2>
   1.529 +<title>Identifying mistakes in style files</title>
   1.530 +
   1.531 +<para>If Mercurial encounters a problem in a style file you are working on,
   1.532 +it prints a terse error message that, once you figure out what it
   1.533 +means, is actually quite useful.
   1.534 +</para>
   1.535 +
   1.536 +<para><!-- &interaction.template.svnstyle.syntax.input; -->
   1.537 +</para>
   1.538 +
   1.539 +<para>Notice that <filename>broken.style</filename> attempts to define a
   1.540 +<literal>changeset</literal> keyword, but forgets to give any content for it.
   1.541 +When instructed to use this style file, Mercurial promptly complains.
   1.542 +</para>
   1.543 +
   1.544 +<para><!-- &interaction.template.svnstyle.syntax.error; -->
   1.545 +</para>
   1.546 +
   1.547 +<para>This error message looks intimidating, but it is not too hard to
   1.548 +follow.
   1.549 +</para>
   1.550 +
   1.551 +<itemizedlist>
   1.552 +<listitem><para>The first component is simply Mercurial's way of saying <quote>I am
   1.553 +  giving up</quote>.
   1.554 +</para>
   1.555 +</listitem><programlisting>
   1.556 +<listitem><para>    <emphasis role="bold">abort:</emphasis> broken.style:1: parse error
   1.557 +</para>
   1.558 +</listitem></programlisting>
   1.559 +
   1.560 +</para>
   1.561 +</listitem>
   1.562 +<listitem><para>Next comes the name of the style file that contains the error.
   1.563 +</para>
   1.564 +</listitem><programlisting>
   1.565 +<listitem><para>    abort: <emphasis role="bold">broken.style</emphasis>:1: parse error
   1.566 +</para>
   1.567 +</listitem></programlisting>
   1.568 +
   1.569 +</para>
   1.570 +</listitem>
   1.571 +<listitem><para>Following the file name is the line number where the error was
   1.572 +  encountered.
   1.573 +</para>
   1.574 +</listitem><programlisting>
   1.575 +<listitem><para>    abort: broken.style:<emphasis role="bold">1</emphasis>: parse error
   1.576 +</para>
   1.577 +</listitem></programlisting>
   1.578 +
   1.579 +</para>
   1.580 +</listitem>
   1.581 +<listitem><para>Finally, a description of what went wrong.
   1.582 +</para>
   1.583 +</listitem><programlisting>
   1.584 +<listitem><para>    abort: broken.style:1: <emphasis role="bold">parse error</emphasis>
   1.585 +</para>
   1.586 +</listitem></programlisting>
   1.587 +<listitem><para>  The description of the problem is not always clear (as in this
   1.588 +  case), but even when it is cryptic, it is almost always trivial to
   1.589 +  visually inspect the offending line in the style file and see what
   1.590 +  is wrong.
   1.591 +</para>
   1.592 +</listitem></itemizedlist>
   1.593 +
   1.594 +</sect2>
   1.595 +<sect2>
   1.596 +<title>Uniquely identifying a repository</title>
   1.597 +
   1.598 +<para>If you would like to be able to identify a Mercurial repository
   1.599 +<quote>fairly uniquely</quote> using a short string as an identifier, you can
   1.600 +use the first revision in the repository.
   1.601 +<!-- &interaction.template.svnstyle.id; -->
   1.602 +This is not guaranteed to be unique, but it is nevertheless useful in
   1.603 +many cases.
   1.604 +</para>
   1.605 +<itemizedlist>
   1.606 +<listitem><para>It will not work in a completely empty repository, because such
   1.607 +  a repository does not have a revision zero.
   1.608 +</para>
   1.609 +</listitem>
   1.610 +<listitem><para>Neither will it work in the (extremely rare) case where a
   1.611 +  repository is a merge of two or more formerly independent
   1.612 +  repositories, and you still have those repositories around.
   1.613 +</para>
   1.614 +</listitem></itemizedlist>
   1.615 +<para>Here are some uses to which you could put this identifier:
   1.616 +</para>
   1.617 +<itemizedlist>
   1.618 +<listitem><para>As a key into a table for a database that manages repositories
   1.619 +  on a server.
   1.620 +</para>
   1.621 +</listitem>
   1.622 +<listitem><para>As half of a {<emphasis>repository ID</emphasis>, <emphasis>revision ID</emphasis>} tuple.
   1.623 +  Save this information away when you run an automated build or other
   1.624 +  activity, so that you can <quote>replay</quote> the build later if necessary.
   1.625 +</para>
   1.626 +</listitem></itemizedlist>
   1.627 +
   1.628 +</sect2>
   1.629 +<sect2>
   1.630 +<title>Mimicking Subversion's output</title>
   1.631 +
   1.632 +<para>Let's try to emulate the default output format used by another
   1.633 +revision control tool, Subversion.
   1.634 +<!-- &interaction.template.svnstyle.short; -->
   1.635 +</para>
   1.636 +
   1.637 +<para>Since Subversion's output style is fairly simple, it is easy to
   1.638 +copy-and-paste a hunk of its output into a file, and replace the text
   1.639 +produced above by Subversion with the template values we'd like to see
   1.640 +expanded.
   1.641 +<!-- &interaction.template.svnstyle.template; -->
   1.642 +</para>
   1.643 +
   1.644 +<para>There are a few small ways in which this template deviates from the
   1.645 +output produced by Subversion.
   1.646 +</para>
   1.647 +<itemizedlist>
   1.648 +<listitem><para>Subversion prints a <quote>readable</quote> date (the <quote>\texttt{Wed, 27 Sep
   1.649 +    2006}</quote> in the example output above) in parentheses.  Mercurial's
   1.650 +  templating engine does not provide a way to display a date in this
   1.651 +  format without also printing the time and time zone.
   1.652 +</para>
   1.653 +</listitem>
   1.654 +<listitem><para>We emulate Subversion's printing of <quote>separator</quote> lines full of
   1.655 +  <quote><literal>-</literal></quote> characters by ending the template with such a line.
   1.656 +  We use the templating engine's <literal role="template-keyword">header</literal> keyword to print a
   1.657 +  separator line as the first line of output (see below), thus
   1.658 +  achieving similar output to Subversion.
   1.659 +</para>
   1.660 +</listitem>
   1.661 +<listitem><para>Subversion's output includes a count in the header of the number
   1.662 +  of lines in the commit message.  We cannot replicate this in
   1.663 +  Mercurial; the templating engine does not currently provide a filter
   1.664 +  that counts the number of lines the template generates.
   1.665 +</para>
   1.666 +</listitem></itemizedlist>
   1.667 +<para>It took me no more than a minute or two of work to replace literal
   1.668 +text from an example of Subversion's output with some keywords and
   1.669 +filters to give the template above.  The style file simply refers to
   1.670 +the template.
   1.671 +<!-- &interaction.template.svnstyle.style; -->
   1.672 +</para>
   1.673 +
   1.674 +<para>We could have included the text of the template file directly in the
   1.675 +style file by enclosing it in quotes and replacing the newlines with
   1.676 +<quote><literal>\n</literal></quote> sequences, but it would have made the style file too
   1.677 +difficult to read.  Readability is a good guide when you're trying to
   1.678 +decide whether some text belongs in a style file, or in a template
   1.679 +file that the style file points to.  If the style file will look too
   1.680 +big or cluttered if you insert a literal piece of text, drop it into a
   1.681 +template instead.
   1.682 +</para>
   1.683 +
   1.684 +</sect2>
   1.685 +</sect1>
   1.686 +</chapter>
   1.687 +
   1.688 +<!--
   1.689 +local variables: 
   1.690 +sgml-parent-document: ("00book.xml" "book" "chapter")
   1.691 +end:
   1.692 +-->
   1.693 \ No newline at end of file