summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/generic/FAQ-en/html/FAQ-patch.html
blob: 9b98b33c6323ca89c9312bde8335d3b76f237d03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<head>
<title>UK TeX FAQ -- question label patch</title>
</head><body>
<h3>Patching existing commands</h3>
<p/>In the general case (possibly sticking something in the middle of an
existing command) this is difficult.  However, the common requirement,
to add some code at the beginning or the end of an existing command,
is conceptually quite easy.  Suppose we want to define a version of a
command that does some small extension of its original definition: we
would naturally write:
<blockquote>
<pre>
\renewcommand{\splat}{\mumble\splat}
</pre>
</blockquote><p>
However, this would not work: a call to <code>\</code><code>splat</code> would execute
<code>\</code><code>mumble</code>, and the call the redefined <code>\</code><code>splat</code> again; this is an
unterminated recursion, that will quickly exhaust TeX&rsquo;s memory.
<p/>Fortunately, the TeX primitive <code>\</code><code>let</code> command comes to our
rescue; it allows us to take a &ldquo;snapshot&rdquo; of the current state of a
command, which we can then use in the redefinition of the command.
So:
<blockquote>
<pre>
\let\OldSmooth\smooth
\renewcommand{\smooth}{\mumble\OldSmooth}
</pre>
</blockquote><p>
effects the required patch, safely.  Adding things at the end of a
command works similarly.  If <code>\</code><code>smooth</code> takes arguments, one must
pass them on:
<blockquote>
<pre>
\let\OldSmooth\smooth
\renewcommand{\smooth}[2]{\mumble\OldSmooth{#1}{#2}}
</pre>

</blockquote><p>
<p/>The general case may be achieved in two ways.  First, one can use the
LaTeX command <code>\</code><code>CheckCommand</code>; this compares an existing command
with the definition you give it, and issues a warning if two don&rsquo;t
match.  Use is therefore:
<blockquote>
  <code>\CheckCommand{\complex}{</code>&lt;<i>original definition</i>&gt;<code>}</code><br>
  <code>\renewcommand{\complex}{</code>&lt;<i>new definition</i>&gt;<code>}</code>
</blockquote><p>
This technique is obviously somewhat laborious, but if the original
command comes from a source that&rsquo;s liable to change under the control
of someone else, it does at least warn you that your patch is in
danger of going wrong.
<p/>Otherwise, LaTeX users may use one of the <i>patchcmd</i>,
<i>ted</i> or <i>etoolbox</i> packages.
<p/>The <i>patchcmd</i> package addresses a slightly simpler task, by
restricting the set of commands that you may patch; you mayn&rsquo;t patch
any command that has an optional argument, though it does deal with
the case of commands defined with <code>\</code><code>DeclareRobustCommand</code>.  The
package defines a <code>\</code><code>patchcommand</code> command, that takes three
arguments: the command to patch, stuff to stick at the front of its
definition, and stuff to stick on the end of its definition.  So,
after
<blockquote>
<pre>
\def\b{b}
\patchcmd\b{a}{c}
</pre>
</blockquote><p>
we will have a new version of <code>\</code><code>b</code> defined as &ldquo;<code>abc</code>&rdquo;.
<p/>The <i>ted</i> package is a &lsquo;token list editor&rsquo;, and provides a
command <code>\</code><code>substitute</code> which will patch the
contents of a macro, putting the result in a token-list, or
(in the form <code>\</code><code>Substitute*</code>) using the result to (re)define a
macro.  The following example defines a simple macro, and then changes
its definition:
<blockquote>
<pre>
\newcommand{\myfont}%
    {\Large\sffamily\selectfont}
\Substitute*[\renewcommand{\myfont}]{\myfont}%
    {\Large\sffamily}{\huge\itshape}
</pre>
</blockquote><p>
The macro&rsquo;s definition is now:
<blockquote>
<pre>
\huge\itshape\selectfont
</pre>
</blockquote><p>
<p/>The package also offers a command <code>\</code><code>ShowTokens</code>, which shows the
content of its argument, one token to a line, with details of the
token&rsquo;s category code, etc.  This is recommended as a debugging tool.
<p/>The <i>etoolbox</i> (which provides user access to e-TeX&rsquo;s
programming facilities) provides a command <code>\</code><code>patchcmd</code> which is
very similar to <code>\</code><code>Substitute</code>, except that it only replaces a
single instance of the token(s) in its search pattern.  Since not all
commands may be patched in this way, <code>\</code><code>patchcmd</code> takes extra
arguments for <em>success</em> and <em>failure</em> cases.  The
package also provides commands that prepend (<code>\</code><code>pretocmd</code>) or append
(<code>\</code><code>apptocmd</code>) to the definition of a command.  Not all commands may
be patched in this way; the package provides a command
<code>\</code><code>ifpatchable</code> which checks the prerequisites, and checks that the
target command&rsquo;s body does indeed include the patch string you propose
to use.  (The command <code>\</code><code>ifpatchable*</code> omits the test on the patch
string.)
<p/>Finally, we&rsquo;ll briefly consider a package that is (just about)
usable, but not really recommendable.  <i>Patch</i> gives you an
ingenious (and difficult to understand) mechanism, and comes as an
old-style LaTeX documented macro file, which can no longer be
processed to <a href="FAQ-install-doc.html">produce formatted documentation, etc.</a>.
Fortunately, the file (<i>patch.doc</i>) may be input directly, and
&ldquo;documentation&rdquo; may found by reading the source of the package.
Roughly speaking, one gives the command a set of instructions
analogous to <i>sed</i> substitutions, and it regenerates the
command thus amended.  Unless you can&rsquo;t do your job any other way,
<i>patch</i> is best avoided.
<dl>
<dt><tt><i>etoolbox.sty</i></tt><dd><a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/etoolbox.zip">macros/latex/contrib/etoolbox</a> (or <a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/etoolbox/">browse the directory</a>)
<dt><tt><i>patch.doc</i></tt><dd><a href="http://www.tex.ac.uk/tex-archive/macros/generic/misc/patch.doc">macros/generic/misc/patch.doc</a>
<dt><tt><i>patchcommand.sty</i></tt><dd><a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/patchcmd.zip">macros/latex/contrib/patchcmd</a> (or <a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/patchcmd/">browse the directory</a>)
<dt><tt><i>ted.sty</i></tt><dd><a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/ted.zip">macros/latex/contrib/ted</a> (or <a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/ted/">browse the directory</a>)
</dl>
<p/><p>This question on the Web: <a href="http://www.tex.ac.uk/cgi-bin/texfaq2html?label=patch">http://www.tex.ac.uk/cgi-bin/texfaq2html?label=patch</a>
</body>