hgbook
annotate fr/ch11-template.xml @ 964:6b680d569bb4
deleting a bunch of files not longer necessary to build the documentation.
Adding missing newly files needed to build the documentation
Adding missing newly files needed to build the documentation
author | Romain PELISSE <belaran@gmail.com> |
---|---|
date | Sun Aug 16 04:58:01 2009 +0200 (2009-08-16) |
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><br/></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<br/>\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 <bos@serpentine.com></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 <bos@serpentine.com></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>&</literal></quote>, <quote><literal><</literal></quote> and <quote><literal>></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 <bos@serpentine.com></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 <bos@serpentine.com></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 --> |