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 | 390 |
1 files changed, 364 insertions, 26 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 b6b706555aa..b91150cbe73 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.28 2012/02/18 19:28:56 rf10 Exp rf10 $ +% $Id: faq-mac-prog.tex,v 1.33 2012/12/07 19:34:33 rf10 Exp rf10 $ \section{Macro programming} @@ -185,6 +185,257 @@ which rather spoils the intent of the joke implicit in the example \csx{cul8r}! \LastEdit*{2009-06-03} +\Question[Q-repeat-num]{Repeating a command \emph{n} times} + +\tex{} \emph{isn't} a programming language, but there are occasions +when you want to repeat some part of your document, just as parts of +programs need to run several times. An obvious +example is \tex{}-based drawing: \latex{}'s \environment{picture} +environment and \Package{pgf} (at least) provide repeat facilities~--- +they are useful for drawing repeating patterns. + +This answer deals with repeating an operation a given number of times; +repeating operations once for each of a set of objects is dealt with +in the answer \Qref*{repeating ``over a set''}{Q-repeat-set}. + +Plain \tex{} itself provides a \csx{loop} \dots{} \csx{repeat} +contruct, which enables you to repeat a command (or set of commands). +The syntax is simple enough, but it use of \tex{} conditionals is +different enough that many people find it confusing. +\begin{quote} +\begin{verbatim} +\newcount\foo +\foo=10 +\loop + \message{\the\foo} + \advance \foo -1 +\ifnum \foo>0 +\repeat +\end{verbatim} +\end{quote} +In this slightly tricky code, \csx{loop} starts the construct ended by +\csx{repeat}, but \csx{repeat} also ``serves as'' the \csx{fi} to the +\csx{ifnum}. The loop above prints the numbers from 10 down to 1 via +\tex{} \csx{message} (i.e., on the console output). + +The \Package{multido} package is also `generic' (usable both in +\plaintex{} and latex{}); it defines a command \csx{multido} with +three arguments: +\begin{quote} + % ! line break + \cmdinvoke{multido}{\meta{variables}}{\meta{repetitions}}{\meta{stuff to repeat}} +\end{quote} +When the macro is executing, the \meta{stuff to repeat} gets executed +\meta{repetitions} times; the \meta{variables} gives a list of +variables that can be used in \meta{stuff}. Each variable is a +composite of a command sequence and how it varies; so a variable +``\csx{iz}\texttt{=2+4}'' sets \csx{iz} to \texttt{2} first time +around, then \texttt{6} and \texttt{10} in the next two iterations, +and so on. (The variable \csx{iz} is an integer; variables with other +initial letters represent different data types.) + +% [do these things matter?] +% The \latexe{} kernel has commands \csx{@for} and \csx{@tfor}. +% +% The \latex{}3 kernel includes the command |\prg_replicate:nn|; this +% information isn't much use unless you're a \latex{}3 user. +Both current \latex{} and (experimental) \latex{}3 have iteration +commands for internal use and for package writers; their use is +probably not recommendable. + +The \latex{} distribution package \Package{ifthen} offers the macro +\csx{whiledo}: +\begin{quote} +\begin{verbatim} +\newcounter{ct} +... +\setcounter{ct}{1} +\whiledo {\value{ct} < 5}% +{% + \thect\ + \stepcounter {ct}% +} +\end{verbatim} +\end{quote} + +The \Package{forloop} package provides nothing but \csx{forloop}: +\begin{quote} +\begin{verbatim} +\newcounter{ct} +... +\forloop{ct}{1}{\value{ct} < 5}% +{% + \thect\ +} +\end{verbatim} +\end{quote} +as you can see, the arguments are counter, starting value and +termination condition; an optional argument supplies a step value +(default step is 1). + +The \latex{} \environment{picture} environment has a simple command +for repeated drawing: +\begin{quote} +\begin{verbatim} +\multiput(x,y)(xstep,ystep){n}{obj} +\end{verbatim} +\end{quote} +which places \meta{obj} (intended to be a bit of picture) +\meta{n} times at positions (\meta{x}, \meta{y}), +(\meta{x}+\meta{xstep}, \meta{y}+\meta{ystep}), +(\meta{x}+2\meta{xstep}, \meta{y}+2\meta{ystep}) and so on, adding the +displacement again each time. The command was designed for use in +\environment{picture}, but it makes no check, and may even be used to +provide eccentric typesetting in a ``regular'' sentence, such as: +\begin{quote} +\begin{verbatim} +Here \multiput(0,0)(1,1){3}{we} are again. +\end{verbatim} +\end{quote} +with predictable (if not actually desirable) effect. It may be used +with nothing but an iterative calculation in the braced argument, in +which case its graphical capabilities have no effect. + +The \Package{pgffor} package, which is part of the % ! line break +\Qref*{\Package{pgf} distribution}{Q-drawing}, also +provides iterations to support the needs of graphics. Its syntax is +in the style of common programming languages: +\begin{quote} +\begin{verbatim} +\usepackage{pgffor} +\newcommand{\cmd}{-x-} +... +\foreach \n in {1,...,4}{\cmd{}} +\end{verbatim} +\end{quote} +typesets ``\texttt{-x-\relax-x-\relax-x-\relax-x-}'' + +The \csx{foreach} command has the potential drawback that its repeated +unit is executed in a group, so that any calculations done within the +loop are lost (unless their result is made \csx{global}); however, it +does not `build in' its graphical origins (as \csx{multiput} does) so +its potential outside its own graphics environment ``home'' is more +clear. +% +%% can't convince myself that \naturalloop helps with anything +% The \Package{etextools} package provides \csx{naturalloop}, which +% repeats material according to a count argument that you give it. +% +%% this stuff removed, following the observation that the package's use +%% of \repeat is inconsistent with both plain tex and latex; pity -- +%% it's a nice package apart from being totally unusable :-( +% +% The \Package{repeat} package provides a \csx{for} command that +% encompasses a lot of the above; for example: +% \begin{quote} +% \begin{verbatim} +% \input repeat +% \newcount\foo +% \repeat +% \for{foo} \from{1} \to{10} \do{x*} +% \end{verbatim} +% \end{quote} +% which will typeset \texttt{x*} ten times (the count \csx{foo} will +% end up with value 11). +% +% Note the \plaintex{} usage: \Package{repeat} is ``generic'' and +% defines commands that are comfortable to \plaintex{} users, while +% remaining usable by \latex{} users. +% +% The complete syntax is given in the meta-expression: +% \begin{quote} +% \begin{verbatim} +% \repeat +% \for{var} +% \from{<start>} \by{<step>} \to{<end>} +% \downto{<end>} \until{<cond>} \while{<cond>} +% \do{<operate on something>} +% \end{verbatim} +% \end{quote} +% You must choose a consistent set of \csx{from}, \csx{by}, \csx{to}, +% \csx{downto}, \csx{until} and \csx{while} (none is actually required, +% but of course any loop has to have \emph{some}). + +% In summary, while it is certainly possible to write this sort of code as +% a private project (for example, using the \etex{} \csx{numexpr} +% primitive), one cannot deny that plenty of choice for the task is +% readily available. +% +% (the above ignore Pic\tex{}, which almost certainly has similar +% functions, but in the absence of a manual\dots{}) +\begin{ctanrefs} +%\item[etextools.sty]\CTANref{etextools} +\item[forarray.sty]\CTANref{forarray} +\item[forloop.sty]\CTANref{forloop} +\item[ifthen.sty]Distributed as part of \CTANref{latex} +\item[multido.sty]\CTANref{multido} +\item[pgffor.sty]Distributed as part of \CTANref{pgf} +%\item[repeat.tex]\CTANref{repeat} +\end{ctanrefs} + +\Question[Q-repeat-set]{Repeating something for each `thing' in a set} + +A common alternative requirement is to repeatedly apply a command to a +set of ``objects''; this can arise, for example, when you have input +that specifies a list. + +The \Package{etoolbox} package provides iteration over a +comma-separated list of items, in its \csx{docsvlist} and +\csx{forcsvlist} commands; they are well-described in the package +documentation. The \Package{datatool} package manages ``databases'' +(of its own definition) and you may iterate over entries in such a +database using the command \csx{DTLforeach}. + +The \Package{forarray} package defines its own ``list'' and ``array'' +structures, together with commands \csx{ForEach} and \csx{ForArray} +which enable a command to be executed for each element in a list or +array, respectively. + +The \Package{dowith} defines a pair of macros \csx{DoWith} and +\csx{StopDoing} that process each ``thing'' between them; a trivial +example of use is: +\begin{quote} +\begin{verbatim} +\usepackage{dowith} +... +\begin{document} +\newcommand{\foo}[1]{\message{#1+} +\DoWith\foo a{BBB}c\StopDoing +\end{verbatim} +\end{quote} +which produces terminal output: +\begin{quote} +\begin{verbatim} +a+ BBB+ c+ +\end{verbatim} +\end{quote} +so, the macros have found 3 ``things'', including one with braces +around it. (The interpolated spaces come from the primitive +\csx{message} command.) + +The only constraint is that all commands in the enclosed stuff are +``expandable'' (which means, for example, that you may not use +commands with optional arguments). + +From the same stable (as \Package{dowith}) comes the package +\Package{commado}, that provides commands \csx{DoWithCSL} (apply a +command to each element of a comma-separated-variable list) and +\csx{DoWithBasesExts} (apply a command to each of a set of files, +defined by base name and ``extension''). Use of these \csx{DoWith*} +macros is also expandable (if the command applied to the list elements +is itself expandable). +\begin{ctanrefs} +\item[commado.sty]\CTANref{commado} +\item[datatool.sty]\CTANref{datatool} +\item[dowith.sty]\CTANref{dowith} +\item[etoolbox.sty]\CTANref{etoolbox} +\item[filesdo.sty]Distributed with \CTANref{commado} +\end{ctanrefs} +\LastEdit{2013-02-20} + +%See \url{http://tex.stackexchange.com/questions/16189/repeat-command-n-times} +%for details (do i need this any more?) + \Question[Q-findwidth]{Finding the width of a letter, word, or phrase} Put the word in a box, and measure the width of the box. For example, @@ -224,7 +475,7 @@ would naturally write: \end{verbatim} \end{quote} However, this would not work: a call to \csx{splat} would execute -\csx{mumble}, and the call the redefined \csx{splat} again; this is an +\csx{mumble}, and then call the redefined \csx{splat} again; this is an `unterminated recursion', that will quickly exhaust \TeX{}'s memory. Fortunately, the \TeX{} primitive \csx{let} command comes to our @@ -343,7 +594,7 @@ The package also offers a command \csx{ShowTokens}, which shows the content of its argument, one token to a line, with details of the token's category code, etc. This is recommended as a debugging tool. -The \Package{etoolbox} (which provides user access to \eTeX{}'s +The \Package{etoolbox} package (which provides user access to \eTeX{}'s programming facilities) provides a command \csx{patchcmd} which is very similar to \csx{Substitute}, except that it only replaces a single instance of the token(s) in its search pattern. Since not all @@ -357,6 +608,13 @@ target command's body does indeed include the patch string you propose to use. (The command \csx{ifpatchable*} omits the test on the patch string.) +The \Package{regexpatch} package deals with cases that are +inaccessible with \Package{etoolbox}; it uses the regular expression +(pattern-matching) package \Package{l3regex} from the \latex{}3 +distribution to find the code you need to patch. The package also +``knows about'' robust commands and about +\Qref*{\Package{biblatex}}{Q-biblatex}. + Finally, we'll briefly consider a package that is (just about) usable, but not really recommendable. \Package{Patch} gives you an ingenious (and difficult to understand) mechanism, and comes as an @@ -370,12 +628,14 @@ command thus amended. Unless you can't do your job any other way, \Package{patch} is best avoided. \begin{ctanrefs} \item[etoolbox.sty]\CTANref{etoolbox} +\item[l3regex.sty]Distributed as part of \CTANref{l3experimental}[l3regex] \item[letltxmacro.sty]Distributed as part of \CTANref{oberdiek}[letltxmacro] \item[patch.doc]\CTANref{patch} \item[patchcommand.sty]\CTANref{patchcmd} +\item[regexpatch.sty]\CTANref{regexpatch} \item[ted.sty]\CTANref{ted} \end{ctanrefs} -\LastEdit{2011-06-29} +\LastEdit{2012-12-21} \Question[Q-compjobnam]{Comparing the ``job name''} @@ -2002,7 +2262,7 @@ Using a \tex{} executable of some sort, the simple answer is to try (I've rearranged the output there, from the rather confused version \TeX{} itself produces.) -We may perhaps, now, wonder about \csx{@unexpandable@protect}: +So, what about \csx{@unexpandable@protect}?: \begin{quote} \begin{verbatim} *\show\@unexpandable@protect @@ -2038,6 +2298,8 @@ shown below, and simply execute the command to find its definition: 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.) +% Similar provisions are made in the package \Package{show2e} but i +% don't understand them yet... The command \ProgName{texdef} (or \ProgName{latexdef}~--- the same command with a different name) will do all that for you and return the @@ -2045,15 +2307,12 @@ results slightly more tidily than \latex{} itself manages. For example: \begin{quote} \begin{verbatim} -latexdef texttt +$ latexdef texttt \end{verbatim} \end{quote} gives: \begin{quote} \begin{verbatim} -$ latexdef texttt - -\texttt: macro:->\protect \texttt \texttt : @@ -2067,6 +2326,59 @@ macro:->\protect \texttt \ProgName{latexdef} has useful `intelligence' in it, as it has spotted and dealt with the \csx{protect}.) +With the \texttt{-s} switch, \ProgName{latexdef} will give you a +source location: +\begin{quote} +\begin{verbatim} +$ latexdef -s texttt +% latex.ltx, line 3736: +\DeclareTextFontCommand{\texttt}{\ttfamily} +\end{verbatim} +\end{quote} +though one should note that it doesn't give you the detail of the +actual coding, merely the definition's location. + +Environments also surrender their details to \ProgName{latexdef}: +\begin{quote} +\begin{wideversion} +\begin{verbatim} +$ latexdef -E itemize + +\itemize: +macro:->\ifnum \@itemdepth >\thr@@ \@toodeep + \else \advance \@itemdepth \@ne + \edef \@itemitem {labelitem\romannumeral \the \@itemdepth}% + \expandafter \list \csname \@itemitem \endcsname + {\def \makelabel ##1{\hss \llap {##1}}}% + \fi + +\enditemize: +macro:->\global \advance \@listdepth \m@ne \endtrivlist +\end{verbatim} +\end{wideversion} +\begin{narrowversion} +\begin{verbatim} +$ latexdef -E itemize + +\itemize: +macro:->\ifnum \@itemdepth >\thr@@ \@toodeep + \else \advance \@itemdepth \@ne + \edef \@itemitem {labelitem\romannumeral + \the \@itemdepth}% + \expandafter \list + \csname \@itemitem \endcsname + {\def \makelabel ##1{\hss \llap {##1}}}% + \fi + +\enditemize: +macro:->\global \advance \@listdepth \m@ne + \endtrivlist +\end{verbatim} +\end{narrowversion} +\end{quote} +(Yet again, this is a sanitised version of the macro definition +output, which appears as a single very wide line for each definition.) + 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}). @@ -2134,7 +2446,7 @@ distribution. \item[\nothtml{\rmfamily}\LaTeX{} distribution]\CTANref{latex} \item[texdef, \nothtml{{\rmfamily aka }}latexdef]\CTANref{texdef} \end{ctanrefs} -\LastEdit{2011-03-17} +\LastEdit{2012-10-09} \Question[Q-oarglikesect]{Optional arguments like \csx{section}} @@ -2386,24 +2698,17 @@ normal \tex{}-style mandatory argument, and appears as \texttt{\#2}. While \Package{xparse} provides pleasing command argument specifications, it \emph{is} part of the % ! line break -\Qref*{\latex{}~3 experimental harness}{Q-LaTeX3}, and -simply loading the package ``pulls in'' a large bunch of other package -files via the \Package{expl3} package: these packages provide the rest -of the harness. -% original suggestion was to offer: -% \NewDocumentCommand{\mycommand}{s}{% -% % macro contents where #1 refers to *-variant (true) or not (false) -% \IfBooleanTF{#1}% Condition on * -% {}% TRUE: \mycommand* -% {}% FALSE: \mycommand -% } +\Qref*{\latex{}~3 experimental harness}{Q-LaTeX3}. +Simply loading the package to provide \csx{DeclareDocumentCommand} +``pulls in'' all of the \latex{}3 kernel (a large bunch of packages) +via the \Package{expl3} package. \begin{ctanrefs} \item[ifthen.sty]Part of the \LaTeX{} distribution \item[suffix.sty]Distributed as part of \CTANref{bigfoot}[suffix] \item[xparse.sty]Distributed as part of \CTANref{l3packages}[xparse] \item[expl3.sty]Distributed as part of \CTANref{l3kernel}[expl3] \end{ctanrefs} -\LastEdit{2012-02-07} +\LastEdit{2012-11-01} \nothtml{\hrule height 0pt \nobreak\vskip0pt plus2.5in\vskip 0pt\relax} \Question[Q-ltxabbrv]{\LaTeX{} internal ``abbreviations'', etc.} @@ -2910,8 +3215,36 @@ offers. Koma-Script's supporting command: \cmdinvoke{ifthispageodd}{<true>}{<false>} \end{quote} executes different things depending on the page number. + +The package \Package{ifoddpage} is designed to provide the same +facility; crucially, it can behave ``sensibly'' even if you are +typesetting for one-side printing only; like the \Package{changepage} +it uses a `check' command \csx{checkoddpage}. The conditional `side' +flags are set using (Plain) \TeX{} conditionals; they are defined +locally, so that you can minimise their use of \tex{} workspace~--- +see the package documentation for the somewhat tricky sequence +involved. In addition the package provides a command +\csx{ifoddpageoroneside}, which is true on odd pages of a two-side +document, or on all pages of a one-side document. Usage is: +\begin{quote} +\begin{verbatim} +\checkoddpage +\ifoddpage + odd-side text +\else + even-side text +\fi +\end{verbatim} +\end{quote} +The author's recommended usage (trickily) includes the whole operation +in a box; this has the advantage that your test will always work, but +the usual disadvantage that boxes may not split. In common uses, the +whole work will be done inside a box (as, for example, in the case of +a float), so the elaborate work proposed by the author is not +necessary. \begin{ctanrefs} \item[changepage.sty]\CTANref{changepage} +\item[ifoddpage.sty]\CTANref{ifoddpage} \item[ifthen.sty]Part of the \latex{} distribution: \CTANref{latex} \item[\nothtml{\rmfamily}KOMA script bundle]\CTANref{koma-script} \item[memoir.cls]\CTANref{memoir} @@ -3282,7 +3615,7 @@ good read. However, it's always difficult to remember the things you should \emph{not} do, when there are so many things to remember that you -really must do: some automation is needed\dots{}. +really must do: some automation is useful\dots{}. The nicely-named \Package{nag} allows you to apply a configurable set of checks to your document, as you run it through \LaTeX{}; you get @@ -3312,6 +3645,11 @@ Package nag Warning: Command \bf is an old the package provides a demo file which contains most of the sorts of errors you might make~--- the example is one of them). \end{narrowversion} +While \Package{l2tabu} and \Package{nag} alert you to \emph{possible} +programming errors, you should not forget that they are merely +commenting on \emph{style}; don't assume that a \Package{nag} error is +going to damn your code~--- rather, note the issue and try to train +your fingers not to do the same ``next time''. The \ProgName{lacheck} program analyses your source and comments on it; its view of what is ``bad'' is \emph{very} subjective (the @@ -3325,9 +3663,9 @@ doesn't seem as comprehensive as \Package{nag}, but it allows you to download its script, which you can then juggle with to make it more draconian. \begin{ctanrefs} -\item[l2tabu]Browse \CTANref{l2tabu} for a copy in a language that's - convenient for you +\item[l2tabu]Browse \CTANref{l2tabu} for a copy of the document in a + language that is convenient for you \item[lacheck]\CTANref{lacheck} \item[nag.sty]\CTANref{nag} \end{ctanrefs} - +\LastEdit{2012-10-09}
\ No newline at end of file |