diff options
Diffstat (limited to 'Master/texmf-dist/doc/generic/FAQ-en/faq-mac-prog.tex')
-rw-r--r-- | Master/texmf-dist/doc/generic/FAQ-en/faq-mac-prog.tex | 250 |
1 files changed, 186 insertions, 64 deletions
diff --git a/Master/texmf-dist/doc/generic/FAQ-en/faq-mac-prog.tex b/Master/texmf-dist/doc/generic/FAQ-en/faq-mac-prog.tex index d2e379eed88..a3799f9bf03 100644 --- a/Master/texmf-dist/doc/generic/FAQ-en/faq-mac-prog.tex +++ b/Master/texmf-dist/doc/generic/FAQ-en/faq-mac-prog.tex @@ -1,4 +1,4 @@ -% $Id: faq-mac-prog.tex,v 1.13 2011/02/13 23:08:45 rf10 Exp $ +% $Id: faq-mac-prog.tex,v 1.17 2011/03/17 21:18:43 rf10 Exp $ \section{Macro programming} @@ -23,7 +23,7 @@ good: \begin{enumerate} \item Use \csx{csname}\dots\csx{endcsname} to define and invoke the macro: - \begin{quote} +\begin{quote} \begin{narrowversion} \begin{verbatim} \expandafter\newcommand @@ -37,7 +37,7 @@ I said, ``\csname cul8r\endcsname''. I said, ``\csname cul8r\endcsname''. \end{verbatim} \end{wideversion} - \end{quote} +\end{quote} \begin{description} \item[Pro:] No unexpected side effects \item[Con:] So verbose as to be unusable @@ -79,25 +79,25 @@ I said, ``\Remark{cul8r}''. see that you are defining a macro, but others likely won't) \end{description} \item Convince \TeX{} that ``\texttt{8}'' is a letter: - \begin{quote} +\begin{quote} \begin{verbatim} \catcode`8 = 11 \newcommand{\cul8r}{Goodbye!} I said, ``\cul8r''. \end{verbatim} - \end{quote} +\end{quote} \begin{description} \item[Pro:] \csx{cul8r} can be used directly \item[Con:] Likely to break other uses of ``\texttt{8}'' (such as numbers or dimensions; so \cmdinvoke{setlength}{\csx{paperwidth}}{8in} tells us: - \begin{quote} +\begin{quote} \begin{verbatim} ! Missing number, treated as zero. <to be read again> 8 \end{verbatim} - \end{quote} +\end{quote} \end{description} As a general rule, changing category codes is something to use \emph{in extremis}, after detailed examination of options. It is @@ -106,18 +106,18 @@ I said, ``\cul8r''. technique. \item Define a macro \csx{cul} which must always be followed by ``\texttt{8r}'': - \begin{quote} +\begin{quote} \begin{verbatim} \def\cul8r{Goodbye!} I said, ``\cul8r''. \end{verbatim} - \end{quote} +\end{quote} \begin{description} \item[Pro:] \csx{cul8r} can be used directly \item[Con~\#1:] Breaks if \csx{cul} is followed by anything other than ``\texttt{8r}'', with a confusing diagnostic~--- \csx{cul99} produces: - \begin{quote} +\begin{quote} \begin{wideversion} \begin{verbatim} ! Use of \cul doesn't match its definition. @@ -133,7 +133,7 @@ I said, ``\cul8r''. 9 \end{verbatim} \end{narrowversion} - \end{quote} +\end{quote} (which would confuse someone who hadn't even realised there \emph{was} a definition of \csx{cul} in the document). \item[Con~\#2:] Silently redefines existing \csx{cul}, if any; @@ -567,36 +567,82 @@ impossible to program within \TeX{}!). The way to think of this is that |##| gets replaced by |#| in just the same way that |#1| gets replaced by `whatever is the first argument'. -So if you define a macro and use it as: +So if you define a macro: +\begin{quote} +\begin{verbatim} +\newcommand\a[1]{+#1+#1+#1+} +\end{verbatim} +\end{quote} +or (using the \tex{} primitive \csx{def}): +\begin{quote} +\begin{verbatim} +\def\a#1{+#1+#1+#1+} +\end{verbatim} +\end{quote} +and use it as \cmdinvoke{a}{b}, +the macro expansion produces `+b+b+b+', +as most people would expect. + +However, if we now replace part of the macro: \begin{quote} +\begin{narrowversion} +\begin{verbatim} +\newcommand\a[1]{+#1+% + \newcommand\x[1]{xxx#1}} +\end{verbatim} +\end{narrowversion} +\begin{wideversion} \begin{verbatim} -\def\a#1{+++#1+++#1+++#1+++} \a{b} +\newcommand\a[1]{+#1+\newcommand\x[1]{xxx#1}} \end{verbatim} +\end{wideversion} \end{quote} -the macro expansion produces `+++b+++b+++b+++', -which people find normal. However, if we now replace part of the macro: +then \cmdinvoke{a}{b} will give us the rather odd +\begin{quote} + +b+\cmdinvoke{newcommand}{x}[1]{xxxb} +\end{quote} +so that the new \csx{x} ignores its argument. + +If we use the \tex{} primitive: \begin{quote} \begin{verbatim} -\def\a#1{+++#1+++\def\x #1{xxx#1}} +\def\a#1{+#1+\def\x #1{xxx#1}} \end{verbatim} \end{quote} -\cmdinvoke{a}{b} will expand to `+++b+++|\def\x b{xxxb}|'. This +\cmdinvoke{a}{b} will expand to `+b+|\def\x b{xxxb}|'. This defines \csx{x} to be a macro \emph{delimited} by |b|, and taking no -arguments, which people may find strange, even though it is just a -specialisation of the example above. If you want \csx{a} to -define \csx{x} to be a macro with one argument, you need to write: +arguments, which is surely not what was intended! + +Actually, to define \csx{x} to take an argument, we need +\begin{quote} +\begin{narrowversion} +\begin{verbatim} +\newcommand\a[1]{+#1+% + \newcommand\x[1]{xxx##1}} +\end{verbatim} +\end{narrowversion} +\begin{wideversion} +\begin{verbatim} +\newcommand\a[1]{+#1+\newcommand\x[1]{xxx##1}} +\end{verbatim} +\end{wideversion} +\end{quote} +or, using the \tex{} primitive definition: \begin{quote} \begin{verbatim} -\def\a#1{+++#1+++\def\x ##1{xxx##1}} +\def\a#1{+#1+\def\x ##1{xxx##1}} \end{verbatim} \end{quote} -and \csx{a{b}} will expand to -`+++b+++|\def\x #1{xxx#1}|', because |#1| gets replaced by `b' +and \cmdinvoke{a}{b} will expand to +\begin{quote} + +b+|\def\x #1{xxx#1}| +\end{quote} +because |#1| gets replaced by `b' and |##| gets replaced by |#|. -To nest a definition inside a definition inside a definition then -you need |####1|, as at each stage |##| is replaced by -|#|. At the next level you need 8~|#|s each time, and so on. +To nest a definition inside a definition inside a definition then you +need |####1|, doubling the number of |#| signs; and at the next level +you need 8~|#|s each time, and so on. \Question[Q-spinmacro]{Spaces in macros} @@ -1003,11 +1049,12 @@ like: \def z{Yawn, I'm tired}% \end{verbatim} \end{quote} -and each subsequent ``|z|'' in the text would become a yawn. This would be -an astoundingly bad idea for most documents, but might have special -applications. (Note that, in ``|\def z|'', ``|z|'' is no longer interpreted as -a letter; the space is therefore not necessary~--- ``|\defz|'' would do; we -choose to retain the space, for what little clarity we can manage.) +and each subsequent ``\texttt{z}'' in the text would become a +yawn. This would be an astoundingly bad idea for most documents, but +might have special applications. (Note that, in ``\csx{def}\texttt{ + z}'', ``\texttt{z}'' is no longer interpreted as a letter; the space +is therefore not necessary~--- ``\csx{defz}'' would do; we choose to +retain the space, for what little clarity we can manage.) Some \LaTeX{} packages facilitate such definitions. For example, the \Package{shortvrb} package with its \csx{MakeShortVerb} command. @@ -1042,7 +1089,7 @@ For example, the definition } \end{verbatim} \end{quote} -does not work because it attempts to define an ordinary |_| character: +does not work because it attempts to define an ordinary \texttt{\_} character: When the macro is used, the category change does not apply to the underscore character already in the macro definition. Instead, one may use: @@ -1872,8 +1919,8 @@ to patch something to make it ``work the way you want it''. None of these are \emph{pure} motives, but knowledge and expertise seldom arrive through the purest of motives. -The simple answer is to try \csx{show}, in a run of \LaTeX{} that is -taking commands from the terminal: +Using a \tex{} executable of some sort, the simple answer is to try +\csx{show}, in a run that is taking commands from the terminal: \begin{quote} \begin{verbatim} *\makeatletter @@ -1885,8 +1932,9 @@ taking commands from the terminal: \end{verbatim} \end{quote} (I've rearranged the output there, from the rather confused version -\TeX{} itself produces.) We may perhaps, now, wonder about -\csx{@unexpandable@protect}: +\TeX{} itself produces.) + +We may perhaps, now, wonder about \csx{@unexpandable@protect}: \begin{quote} \begin{verbatim} *\show\@unexpandable@protect @@ -1907,7 +1955,7 @@ Many kernel commands are declared robust: \end{verbatim} \end{quote} so that \csx{show} isn't much help. Define a command \csx{pshow} as -shown below, and use that instead: +shown below, and simply execute the command to find its definition: \begin{quote} \begin{verbatim} *\def\pshow#1{{\let\protect\show #1}} @@ -1923,10 +1971,37 @@ Note that the command name that is protected is the `base' command, with a space appended. This is cryptically visible, in a couple of places above. (Again, the output has been sanitised.) -If one has a malleable text editor, the same investigation may more -comfortably be conducted by examining the file \File{latex.ltx} (which -is usually to be found, in a \acro{TDS} system, in directory -\path{tex/latex/base}). +The command \ProgName{texdef} (or \ProgName{latexdef}~--- the same +command with a different name) will do all that for you and return the +results slightly more tidily than \latex{} itself manages. For +example: +\begin{quote} +\begin{verbatim} +latexdef texttt +\end{verbatim} +\end{quote} +gives: +\begin{quote} +\begin{verbatim} +$ latexdef texttt + +\texttt: +macro:->\protect \texttt + +\texttt : +#1->\ifmmode \nfss@text {\ttfamily #1}% + \else \hmode@bgroup \text@command {#1}% + \ttfamily \check@icl #1\check@icr + \expandafter \egroup \fi . +\end{verbatim} +\end{quote} +(again, the output has been sanitised~--- but we see that +\ProgName{latexdef} has useful `intelligence' in it, as it has spotted +and dealt with the \csx{protect}.) + +If one has a malleable text editor, the same investigation may be +conducted by examining the file \File{latex.ltx} (which is usually to +be found, in a \acro{TDS} system, in directory \path{tex/latex/base}). In fact, \File{latex.ltx} is the product of a \ProgName{docstrip} process on a large number of \Qref*{\extension{dtx} files}{Q-dtx}, and @@ -1989,7 +2064,9 @@ All these .dtx files are on \acro{CTAN} as part of the main \LaTeX{} distribution. \begin{ctanrefs} \item[\nothtml{\rmfamily}\LaTeX{} distribution]\CTANref{latex} +\item[texdef, \nothtml{{\rmfamily aka }}latexdef]\CTANref{texdef} \end{ctanrefs} +\LastEdit{2011-03-17} \Question[Q-oarglikesect]{Optional arguments like \csx{section}} @@ -2037,9 +2114,11 @@ you can probably guess the ``simple'' solution to this problem: command relaying. \LaTeX{} allows commands with a single optional argument thus: +\begin{quote} \begin{verbatim} \newcommand{\blah}[1][Default]{...} \end{verbatim} +\end{quote} You may legally call such a command either with its optional argument present, as @@ -2048,18 +2127,20 @@ case, the code of \csx{blah} will have an argument of |Default|. To define a command with two optional arguments, we use the relaying technique, as follows: +\begin{quote} \begin{verbatim} - \newcommand{\blah}[1][Default1]{% - \def\ArgI{{#1}}% - \BlahRelay - } - \newcommand\BlahRelay[1][Default2]{% - % the first optional argument is now in - % \ArgI - % the second is in #1 - ...% - } +\newcommand{\blah}[1][Default1]{% + \def\ArgI{{#1}}% + \BlahRelay +} +\newcommand\BlahRelay[1][Default2]{% + % the first optional argument is now in + % \ArgI + % the second is in #1 + ...% +} \end{verbatim} +\end{quote} Of course, \csx{BlahRelay} may have as many mandatory arguments as are allowed, after allowance for the one taken up with its own optional argument~--- that is, 8. @@ -2565,29 +2646,59 @@ counter that appears in a \csx{pageref} command has been inserted in the course of the output routine, and is therefore safe. However, \csx{pageref} itself isn't reliable: one might hope that +\begin{quote} \begin{verbatim} \ifthenelse{\isodd{\pageref{foo}}}{odd}{even} \end{verbatim} +\end{quote} would do the necessary, but both the \Package{babel} and \Package{hyperref} packages have been known to interfere with the output of \csx{pageref}; be careful! -The \Package{changepage} package needs to provide this functionality for -its own use, and therefore provides a command \csx{checkoddpage}; this -sets a private-use label, and the page reference part of that label is -then examined (in a \Package{hyperref}-safe way) to set a conditional -\csx{ifoddpage} true if the command was issued on an odd page. The -\Class{memoir} class has the same command setting a conditional -\csx{ifoddpage}. Of course, the \csx{label} contributes to \LaTeX{}'s -``Rerun to get cross-references right'' error messages\dots{} +The \Package{changepage} package needs to provide this functionality +for its own use, and therefore provides a command \csx{checkoddpage}; +this sets a private-use `label', and the page reference part of that +label is then examined (in a \Package{hyperref}-safe way) to set a +conditional \csx{ifoddpage} true if the command was issued on an odd +page. (The \Class{memoir} class has the same command.) \latex{} +users who are unfamiliar with \tex{}'s \csx{if...} commands may use +the \Package{ifthen} package: +\begin{wideversion} +\begin{quote} +\begin{verbatim} +\usepackage{ifthen,changepage} +... +\checkoddpage +\ifthenelse{\boolean{oddpage}}{<odd page stuff>}{<even page stuff>} +\end{verbatim} +\end{quote} +\end{wideversion} +\begin{narrowversion} +\begin{quote} +\begin{verbatim} +\usepackage{ifthen,changepage} +... +\checkoddpage +\ifthenelse{\boolean{oddpage}}% + {<odd page stuff>}% + {<even page stuff>} +\end{verbatim} +\end{quote} +\end{narrowversion} + +Of course, the `label' contributes to \LaTeX{}'s ``Rerun to get +cross-references right'' error messages\dots{} The Koma-Script classes have an \environment{addmargin*} environment that also provides the sorts of facilities that the \Package{changepage} -offers. Koma-Script's supporting command is % !line break -\cmdinvoke{ifthispageodd}{<true>}{<false>} executes different things -depending on the page number. +offers. Koma-Script's supporting command: +\begin{quote} +\cmdinvoke{ifthispageodd}{<true>}{<false>} +\end{quote} +executes different things depending on the page number. \begin{ctanrefs} \item[changepage.sty]\CTANref{changepage} +\item[ifthen.sty]Part of the \latex{} distribution: \CTANref{latex} \item[\nothtml{\rmfamily}KOMA script bundle]\CTANref{koma-script} \item[memoir.cls]\CTANref{memoir} \end{ctanrefs} @@ -2901,8 +3012,8 @@ package \Package{fix-cm} which will allow you to use the fonts, within versions of the fonts, most modern distributions will just generate an appropriate bitmap for you. -So, suppose you want to use Computer Modern Roman at 30 points, you -might be tempted to write: +So, suppose you want to produce a heading in Computer Modern Roman at +30 points, you might be tempted to write: \begin{quote} \begin{verbatim} \newfont{\bigfont}{cmr10 at 30pt} @@ -2926,9 +3037,20 @@ Note that the \Package{fix-cm} package was not distributed until the December 2003 edition of \LaTeX{}; if you have an older distribution, the packages \Package{type1cm} (for \acro{CM} fonts) and \Package{type1ec} (for \acro{EC} fonts) are available. + +If \Package{fix-cm} doesn't do the job for you, try one of the other +two; \Package{fix-cm} has one or two omissions~--- fonts the \latex{} +team considered not useful, or something\dots{} + +A further alternative might be to switch to the +\Qref*{\FontName{Latin} \FontName{Modern} fonts}{Q-uselmfonts} (which +provide a close simulacrum of the \FontName{Computer} +\FontName{Modern} set); these fonts were scaleable from their first +distribution, and don't therefore need any such trick as the above. \begin{ctanrefs} \item[fix-cm.sty]Distributed as part of \CTANref{latex}[fix-cm] (an unpacked version is available at \CTANref{fix-cm}) +\item[\nothtml{\rmfamily}\FontName{Latin} \FontName{Modern} fonts]\CTANref{lm} \item[type1cm.sty]\CTANref{type1cm} \item[type1ec.sty]\CTANref{type1ec} (the package is actually part of the \CTANref{cm-super} distribution, but it works happily in |