% \iffalse ********************************************* METACOMMENT % % TeX this file with LaTeX2e ! % % The following files will be written out: % % ==> email.dvi ( Documentation ) % --> email.sty ( LaTeX2e package ) % --> unxparse.sty ( LaTeX2e package ) % % %% Copyright : Kai-Uwe Bux %% --------- Norderneystraße 26 %% D-26419 Schortens/Heidmühle (Germany) %% %% ***************************************************************** % >>>>>>>>> !! Proliferation of UNCHANGED versions of !! <<<<<<<<< % !! this file is permitted !! % % >>>>>>>>> !! Don't change this file without changing !! <<<<<<<<< % !! it's name !! % ****************************************************************** % % \begin{macrocode} \def\FileVersion{0.8 $\alpha$-test} \def\FileDate{1999/08/25} \def\FileDescription{sending LaTeX files by e-mail} % \end{macrocode} % % ********************************************** END METACOMMENT \fi % % \CheckSum{483} % % \iffalse ********************************************* METACOMMENT % \begin{macrocode} %<*driver> \NeedsTeXFormat{LaTeX2e}[1995/12/01] \let\ThisVersion\FileVersion \let\ThisDate\FileDate % % \end{macrocode} % ********************************************** END METACOMMENT \fi % % \iffalse ******************************************** METATCOMMENT % % \begin{macrocode} %<*installation> \ifx\undefined\batchfile\begingroup\newtoks\List\fi \def\batchfile{email.dtx} \makeatletter \let\@@end=\relax \List={} \def\File#1#2{\List=\expandafter{\the\List\file{#1}{\from{email.dtx}{#2}}}} \File{email.sty}{email} \File{unxparse.sty}{unx} \def\G{\expandafter\expandafter\expandafter\generate\expandafter{\the\List}} \def\GenerateAll{\G\let\GenerateAll\relax} \def\StopInput{\endinput\let\StopInput\relax} \input docstrip.tex \GenerateAll \StopInput \endgroup % % \end{macrocode} % % ********************************************** END METACOMMENT \fi % % \iffalse ********************************************* METACOMMENT % % \begin{macrocode} %<*driver> \documentclass[12pt]{ltxdoc} \newcommand{\pkg}[1]{\textsf{#1}} \newcommand{\cls}[1]{\textsf{#1}} \newcommand{\file}[1]{\texttt{#1}} \newcommand{\env}[1]{\texttt{#1}} \newcommand{\opt}[1]{\textsf{#1}} \newcommand{\sect}[1]{{#1}} \newcommand{\sty}[1]{\emph{#1}} \newcommand{\ARG}[1]{\emph{#1}} \newcommand{\GobbleOne}[1]{} \newcommand{\Section}{\newpage\section} \newcommand{\finalnopagebreak}{\nopagebreak} \newcommand{\finalpagebreak}{\pagebreak} \title{Sending \LaTeX-files by \pkg{email}} \author{Kai-Uwe Bux} \date{\begin{tabular}{ll} Date: & \ThisDate\\ Version: & \ThisVersion \end{tabular}} \begin{document} \maketitle \DocInput{email.dtx} \end{document} % % \end{macrocode} % % ********************************************** END METACOMMENT \fi % % \begin{abstract} % \noindent % Sending a \LaTeX-file by email offers different problems. It is % Especially important not to leave out some local packages. % \LaTeX\ offers the \env{filecontents}-environment and |\listfiles| for % this purpose. We will describe a package that generates % a file to be sent by email out of your document automatically. % % Additionally we describe a package \pkg{unxparse} that provides % a Un$*$x-like wildcard mechanism. It is used by \pkg{email} % if available. % \end{abstract} % % \section*{Installation} % In processing the files \file{email.dtx} \TeX\ will write out % the file \file{email.sty} and \file{unxparse.sty}. % You should put it where \TeX\ will search for packages. % % \section*{The user interface} % Suppose you want to send a \LaTeX\ file by e-mail. Of course you don't % want the addressee to have any trouble with your file. He should be % able to typeset it simply by \LaTeX{}ing it. Then you have to do some % work in order to make this possible. The main problem is that you may % have used some local packages not available to the recipient. % The \pkg{email} package is written to reduce your work. % % Let us assume your file is \file{example.tex}. This file looks like % this: % \begin{verbatim} % \documentclass[12pt,english]{article} % \usepackage{babel} % \usepackage{catmac} % ... % \begin{document} % ... % \end{document} % \end{verbatim} % It may be that the addressee does not even know about the % \pkg{catmac} package. Hence you have to put this package into your % email. \LaTeXe\ provides an elegant way to deal with this. You can % transform the file \file{example.tex} into another file % \file{example.mail} like this: % \begin{verbatim} % \begin{filecontents}{catmac.sty} % ... % \end{filecontents} % \documentclass[12pt,english]{article} % \usepackage{babel} % \usepackage{catmac} % ... % \begin{document} % ... % \end{document} % \end{verbatim} % Here the \env{filecontents} environment should contain a verbatim copy % of the \pkg{catmac} package. The file \pkg{example.mail} can be sent % by email. The recipient can typeset it with \LaTeXe\ and then the % following will happen. When \LaTeX\ is processing the \env{filecontens} % environment it checks if the package \pkg{catmac} is already at hand. % If this is not the case it writes out a copy of this file to be % used later on when the line % \begin{verbatim} % \usepackage{catmac} % \end{verbatim} % is being processed. % % What will the \pkg{email} package do for you? Well, in this example % it will write the file \file{example.mail}. It will decide which files % to include and then create that file. Of course it will decide less % sensible than you. For instance the \pkg{email} package would have % put the files used by \pkg{babel} into the file \file{example.mail}. % We will discuss later how to suppress this. But first we will describe % the most elementary way to use the package. % % Just include some lines like the following in the preamble of % your document: % \begin{quote} % |\usepackage{email}|\\ % |\MailFile{|\emph{emfile}|}|\\ % \end{quote} % The first line loads the \pkg{email}-package. The second line % specifies the name of the \ARG{emfile}. This % is the file which will incorporate everything and can be sent by % email. In our example you have to write: % \begin{verbatim} % \documentclass[12pt,english]{article} % \usepackage{babel} % \usepackage{email} % \MailFile{exapmle.mail} % \usepackage{catmac} % ... % \begin{document} % ... % \end{document} % \end{verbatim} % It doesn't matter where you put these two lines exactly. But they % have to appear between |\documentclass| and |\begin{document}|. % Used this way, the \pkg{email} package will copy files to % the \ARG{emfile} \file{example.mail} that you probably won't have % considered. % % Preparing a \LaTeX\ file for email entails the risk of leaving out % a file that is needed. Not all these files show up in the preamble. % Some are hidden because they are used by packages which load them % automatically. To deal with this problem \LaTeX\ provides the % macro |\listfiles| that will put a list of all files used in your % \file{log} file \file{example.log}. The \pkg{email} package will % follow that list leaving out only the standard \LaTeX\ files like % \file{article.cls} or \file{size12.clo}. % % If you want to omit some files that \pkg{email} is inclined to copy % into the \ARG{emfile} you may use a declaration like this: % \begin{quote} % |\usepackage{email}|\\ % |\MailFile{|\emph{emfile}|}|\\ % |\DoNotMail{|\ARG{file$_1$,\ldots,file$_n$}|}| % \end{quote} % In our example: % \begin{verbatim} % \documentclass[12pt,english]{article} % \usepackage{babel} % \usepackage{email} % \MailFile{example.mail} % \DoNotMail{babel.*,*.ldf} % \usepackage{catmac} % ... % \begin{document} % ... % \end{document} % \end{verbatim} % As you can see in this example the use of wildcards is supported. % Here all the ``language definition files'' of the \pkg{babel} package % will be left out. However the use of wildcards is supported only if % the package \pkg{unxparse} is available. In % this case ``$*$'' denotes any (possibly empty) sequence of characters % while ``?'' represents exactly one character. % % The use of |\DoNotMail| can shorten the \ARG{emfile} by a large amount. % You should only exclude \LaTeX\ standard files which are available % on each \LaTeX-installation or files you know the addressee to have % access to. % % There is also a macro |\DoMail| that is similar to % |\DoNotMail| except that it forces a file to be dumped into % \ARG{emfile} even if it is not read during the \TeX\ run. % This goes for \textsf{METAFONT} files that may be needed % in order to generate fonts. The other differences are: % \begin{itemize} % \item % The Arguments of |\DoMail| are not allowed to contain wildcards. % \item % |\DoMail| has higher priority than |\DoNotMail|. Hence you can % reinclude a previously excluded file this way. % \end{itemize} % Don't try to put the \file{aux} or \file{toc} file into your % mail using |\DoMail|. Since these files are open for writing the time % where \pkg{email} copies all the stuff to \ARG{emfile} an attempt % to read the \file{aux} file may have unpredictable consequences. % % Your input file will be processed ordinarily and you will get the % same \file{dvi} output as usual. At the end the % mail file \ARG{emfile} is written and you will be given a list % of all the files included. You will also be given a list of all % files that were required to typeset your document. This information % will help you to decide what can be excluded by |\DoNotMail|. % % \section*{Warning} % There are two things you have to know: % \begin{itemize} % \item % Don't say |\MailFile{example.tex}| in our example. Generally, don't % pass the name of the source file as an argument of % |\MailFile| to the \pkg{email} package. % This would % cause \pkg{email} to try to overwrite the source file. The % consequence will be that the source file gets lost. % \item % The file \ARG{emfile} generated by \pkg{email} is not always % equivalent to the sourcefile due to \TeX's way to deal with % character codes above 127. These will be written as \verb+^^xx+ % to \ARG{emfile}. This has the advantage that \ARG{emfile} can % be processed by all e-mail propgrammes. But within % |\verb+|\ldots|+| this will produce a real difference. You should % be aware of this ``feature''. % \end{itemize} % % \StopEventually{} % % \section*{Implementation} % \LaTeX\ offers the |\listfiles|-macro to get a list of all % files input by \TeX\ during the job. To make this work an internal % list is kept in the macro |\@filelist|. The idea is to use this % list at the end of the document to copy all these file to the % \ARG{emfile}. To do the work of copying we use the % \pkg{verbatim}-packages which is part of the \LaTeX-tools bundle. % % But first we identify the package. % \begin{macrocode} %<*email> \NeedsTeXFormat{LaTeX2e}[1995/12/01] \typeout{Package: `email'. Version: \FileVersion\space of \FileDate.} \ProvidesPackage{email}[\FileDate\space Version: \FileVersion\space LaTeX email package] % \end{macrocode} % We require \pkg{verbatim} if the macro |\MailFile| is undefined. % It will be explained later how it could happen that this macro is % already defined. It indicates that instead of the source file the % file \ARG{emfile} is processed. % In this case the \pkg{verbatim} package is not needed. Otherwise % we are about to generate \ARG{emfile} and we have to use that package. % \begin{macrocode} \@ifundefined{MailFile}{\RequirePackage{verbatim}}{} % \end{macrocode} % The file \pkg{unxparse} is used if available. % \begin{macrocode} \IfFileExists{unxparse.sty}{% \RequirePackage{unxparse} }{} % \end{macrocode} % The macros |\DoNotMail| and |\DoMail| just add their arguments to % the corresponding global lists. % \begin{macrocode} \newcommand{\donot@mail}{} \newcommand{\do@mail}{} % \end{macrocode} % These lists are modified by % appending something like ``,\ARG{file}''. The first comma has to % be removed. Hence the initial value of |\donot@mail| or |\do@mail| % is |\@gobble|. % \begin{macrocode} \let\donot@mail\@gobble \let\do@mail\@gobble % \end{macrocode} % The |\DoNotMail| and |\DoMail| macros are simple now. % \begin{macrocode} \newcommand{\DoNotMail}[1]{% \xdef\donot@mail{\donot@mail,#1}% } \newcommand{\DoMail}[1]{% \xdef\do@mail{\do@mail,#1}% } % \end{macrocode} % Three further variables are introduced now. |\mail@out| is a stream % to write out the \ARG{emfile}. |\||if@mail| is a boolean variable % used to test weather to include a file or not. % And |\is@mailed| is a list macro like |\do@mail|. % \begin{macrocode} \newwrite\mail@out \newif\if@mail \newcommand{\is@mailed}{} \let\is@mailed\@gobble % \end{macrocode} % Here comes the main macro: |\MailFile|. It takes one argument and stores % it away in the macro |\mail@file|. % \begin{macrocode} \providecommand{\MailFile}[1]{% \newcommand\mail@file{#1}% % \end{macrocode} % Then it appends some code to |\enddocument| through the % |\AtEndDocument|-hook. % \begin{macrocode} \AtEndDocument{% \begingroup\setbox200=\vbox{% % \end{macrocode} % This code is a little tricky. We enclose it in a group and in a % |\vbox| which is never shipped out and forgotten after the group. % Otherwise it can happen that \TeX\ builds an extra blank page. % % First we define a macro that deals with lists. We will have to % test if something is an element of the list. We will define a slightly % more general macro that takes three arguments all of which % should be control sequences. The first is a string the second a list % and the third a test with two arguments that expands to |\@firstoftwo| % or |\@secondoftwo|. The macro |\aply@list| will expand to |\@firstoftwo| % if the test is passed for at least one item in the list. % \begin{macrocode} \def\aply@list##1##2##3{% {% \def\lnext{\@secondoftwo}% % \end{macrocode} % Maybe the list is empty. % \begin{macrocode} \ifx##2\@gobble\else \@for\local:=##2\do{% ##3##1\local{\def\lnext{\@firstoftwo}}\relax }% \fi \expandafter}\lnext } % \end{macrocode} % Then we open |\mail@out| and assign it to \ARG{emfile}. % \begin{macrocode} \immediate\openout\mail@out\mail@file % \end{macrocode} % From the package \pkg{verbatim} we take |\verbatim@processline| and % make it writing the current line to |\mail@out|. % \begin{macrocode} \def\verbatim@processline{% \immediate\write\mail@out{\the\verbatim@line}% } % \end{macrocode} % Later on we shall say something like % \begin{quote} % |\@for\in@file:=\@filelist\do{\processfile}|\\ % \ldots\\ % |\@for\in@file:=\do@mail\do{\processfile}| % \end{quote} % to process all the files. The macro % |\processfile| has to do several things. First it has to check if % the file |\in@file| is contained in the list |\donot@mail|. In this % case the file is to be ignored. Otherwise it should be copied to % \ARG{emfile}. But in the second line we have to omit this test % since we want |\DoMail| to override |\DoNotMail|. % Hence we keep it in a macro to be overwritten later on. % \begin{macrocode} \def\test@notmail##1{% \aply@list##1\donot@mail\mail@parse\@mailfalse\relax % \end{macrocode} % There is another chance for the file |\in@file| to be discarded. % We should test if |\in@file| belongs to the \LaTeX\ standard files. This % is done through a macro variable to be defined below. % It performs |\@mailfalse| on standard files. % \begin{macrocode} \if@mail \mail@testlatex \fi } % \end{macrocode} % Now we define |\processfile|. % \begin{macrocode} \def\processfile{% \begingroup % \end{macrocode} % First we perform the test. Since we use \LaTeX's |\@for|-construct % here a second time we have to put all of this stuff within a group. % % First of all we prepare |\in@file|. Maybe it lacks an extension. % \begin{macrocode} \filename@parse\in@file \edef\mail@a{% \filename@area% \filename@base.% \ifx\filename@ext\relax tex% \else\filename@ext\fi% } % \end{macrocode} % Then we go through the list |\donot@mail|. % \begin{macrocode} \@mailtrue \test@notmail\mail@a % \end{macrocode} % We don't want to include a % file twice. Hence we have to check if the file is contained in % |\is@mailed|. Here we use the more primitive |\mail@compare| to be % explained later. Is is analogous to |\mail@parse| but doesn't take % care of wildcards. % \begin{macrocode} \if@mail \aply@list\in@file\is@mailed\mail@compare\@mailfalse\relax \fi % \end{macrocode} % Now |\||if@mail| has the correct value. So we can go on. % The file has not only to be copied but must be surrounded by % |\begin{filecontents}{|\ARG{file}|}| and |\end{filecontents}|. % \begin{macrocode} \if@mail % \end{macrocode} % Since we cannot expect the \env{filecontens} environment to create % a missing directory we have to prepare the file name. % \begin{macrocode} \edef\infile@name{% \filename@base.% \ifx\filename@ext\relax tex% \else\filename@ext\fi% } % \end{macrocode} % Then we start writing % \begin{macrocode} \immediate\write\mail@out {\string\begin{filecontents}{\infile@name}} \expandafter\expandafter\expandafter\verbatiminput \expandafter{\in@file} \immediate\write\mail@out {\string\end\@empty{filecontents}} % \end{macrocode} % The file being copied we pass this information to |\is@mailed|. % \begin{macrocode} \xdef\is@mailed{\is@mailed,\in@file} \fi \endgroup } % \end{macrocode} % Now |\processfile| being defined we can call the main loops. % \begin{macrocode} \ifx\@filelist\@gobble\else \@for\in@file:=\@filelist\do{\processfile} \fi \let\test@notmail\@gobble \ifx\do@mail\@gobble\else \@for\in@file:=\do@mail\do{\processfile} \fi % \end{macrocode} % We should end the mail \ARG{emfile} with a copy of the file % we really want to send. This is the file |\jobname| on which \TeX\ is % working. But wait a minute. If we just make a copy of it, what % would happen when \ARG{emfile} is being processed? Well \ARG{emfile} % as well contains the lines % \begin{quote} % |\usepackage{email}|\\ % |\MailFile{|\ARG{emfile}|}| % \end{quote} % So \ARG{emfile} would try to rewrite itself. This can lead to % desaster. Hence we have to take care about this. We therefore % enclose the line % \begin{quote} % |\newcommand{\MailFile}[1]{}| % \end{quote} % in \ARG{emfile} before the job. Hence |\MailFile| will % be defined when \TeX\ comes to |\usepackage{email}| in processing % \ARG{emfile}. Since we defined |\MailFile| using |\providecommand| % in this package the definition won't change and nothing will happen. % \begin{macrocode} \immediate\write\mail@out {\string\newcommand{\string\MailFile}[1]{}} % \end{macrocode} % Now we finish. We append |\jobname| to \ARG{emfile} and close the % stream |\mail@out|. % \begin{macrocode} \expandafter\expandafter\expandafter\verbatiminput \expandafter{\jobname} \immediate\closeout\mail@out % \end{macrocode} % Now almost everything has been done. The file \ARG{emfile} is % closed and we can show you all the files that were put into it. % We can do this just the way the \LaTeX\ kernel handles |\listfiles|. % But first we have to deal with the format of |\is@mailed| being % either |\@gobble| or a list. % \begin{macrocode} \ifx\is@mailed\@gobble \def\is@mailed{} \fi % \end{macrocode} % Now we borrow code from the kernel writing |\is@mailed| instead of % |\@filelist|. % \begin{macrocode} \typeout{^^J *Files included in \mail@file *}% \@for\@currname:=\is@mailed\do{% \filename@parse\@currname \edef\reserved@a{% \filename@base.% \ifx\filename@ext\relax tex\else\filename@ext\fi% }% \expandafter\let\expandafter\reserved@b \csname ver@\reserved@a\endcsname \expandafter\expandafter\expandafter\@listfiles \expandafter \filename@area\filename@base\\\\\\\\\\\\\\\\\\\@@ \typeout{% \filename@area\reserved@a \ifx\reserved@b\relax\else\@spaces\reserved@b\fi }% } \typeout{ ***********^^J} % \end{macrocode} % Here ends the tricky code. So we can close the box and the group. % \begin{macrocode} }\endgroup% }% % \end{macrocode} % That was the code to be executed at |\end{document}|. But all of % this presupposes that we keep track of the files being read. Hence % |\MailFile| ends by % \begin{macrocode} \listfiles } % \end{macrocode} % % We used |\mail@parse| do decide weather two file names agree. % If \pkg{unxparse} is loaded then we can use |\IfUnxParseThenElse|. % Otherwise we use |\mail@compare|. % \begin{macrocode} \@ifundefined{IfUnxParseThenElse}{% \newcommand{\mail@parse}{\mail@compare} }{% \newcommand{\mail@parse}{\IfUnxParseThenElse} } % \end{macrocode} % Here is the macro that does this trick. It is a little tricky % because we have to deal with the sneaky catcoding tricks of % \LaTeX's font selection algorithm. First we open a group to have % everything local. % \begin{macrocode} \newcommand{\mail@compare}[2]{% {% % \end{macrocode} % The first argument was a completely expanded file name. % The second one has to be parsed here. % \begin{macrocode} \expandafter\def\expandafter\@tempa\expandafter{\csname #1\endcsname}% \filename@parse{#2}% \expandafter\def\expandafter\@tempb\expandafter{% \csname \filename@area% \filename@base.% \ifx\filename@ext\relax tex% \else\filename@ext\fi% \endcsname }% % \end{macrocode} % There is a subtle point within the code above. We used a % |\csname| \ldots\ |\endcsname| brace in the definitions of % |\@tempa| and |\@tempb|. This has the following reason. When % \LaTeX\ loads a font description file on demand the catcodes % of the filename characters are different. \TeX's input and % output primitives don't care about this. But as we want to % compare filenames we will get strange results if we leave the % catcodes untouched. The |\csname| trick allows us to get rid of % different catcodes. So now the comparison will be possible % \begin{macrocode} \ifx\@tempa\@tempb \let\@tempc\@firstoftwo \else \let\@tempc\@secondoftwo \fi % \end{macrocode} % Finally we have to get the definition of |\@tempc| to sneak outside % the group. % \begin{macrocode} \expandafter}\@tempc } % \end{macrocode} % % Now we turn to the problem of dealing with the standard files % in the \LaTeX\ distribution. % For each file that is input through |\input| or something alike % a macro |\ver@...| is being derived from its name and defined to % contain those information specified by |\Provides...|-macros. % If there was a certain format of that info string reserved for % the standard files we could perform a test on |\ver@...| but this % is not the case. Instead there is a file \file{unpack.txt} in every % new \LaTeX\ release that contains the information we are looking for. % % Since it was trivial to use \file{unpack.txt} to create a corresponding % list of |\DoNotMail| instructions we embark on the first idea even % if we cannot hope to be free of bugs in this case. Most \LaTeX\ % standard files contain the phrase ``Standard LaTeX'' after their % version number followed by a specification. % So we will test if this phrase occurs. % \begin{macrocode} \newcommand{\mail@testlatex}{% % \end{macrocode} % Remember that the file to be tested is |\in@file|. We set % |\file@info| to its info string. % \begin{macrocode} \edef\file@info{\csname ver@\in@file\endcsname} \edef\file@info{\file@info} % \end{macrocode} % Now we introduce the |\test| \ldots\ |\end| construction % \begin{macrocode} \def\test##1Standard LaTeX##2\end{% \def\w{##2} \def\e{} \ifx\w\e\else \@mailfalse \fi } % \end{macrocode} % and apply it to |\file@info|. % \begin{macrocode} \expandafter\test\file@info Standard LaTeX\end } % % \end{macrocode} % % \section*{The Un$*$x file name parser for wildcars} % This little package \pkg{unxparse} provides a macro that will % tell if its first argument belongs to regular language described % in the second argument by means of wildcards ``$*$'' and ``?''. % Accordingly it expands to |\@firstoftwo| or |\@secondoftwo|. Hence two % further arguments will be considered. The first % two arguments can be macros. % % First we identify the package % \begin{macrocode} %<*unx> \NeedsTeXFormat{LaTeX2e}[1995/12/01] \typeout{Package: `unxparse'. Version: \FileVersion\space of \FileDate.} \ProvidesPackage{unxparse}[\FileDate\space Version: \FileVersion\space Un*x file name parsing] % \end{macrocode} % The macro |\IfUnxParseThenElse| is defined in the following way. % The |\edef| trick expands macros in the first arguments. % Hence we can assume that |\unx@parse| has strings in the first two % arguments. Note that |\@tempa| is defined locally and expands before % the group to which it is local is closed \emph{in front of it}. % This trick will be used later as well. % \begin{macrocode} \newcommand{\IfUnxParseThenElse}[2]{% {% \edef\@tempa{% \noexpand\unx@parse{#1}{#2}% }% \expandafter}\@tempa } % \end{macrocode} % It remains to implement |\unx@parse|. The idea is to % proceed from left to right ignoring the third and fourth argument % as long as possible. But first we will declare some constants. % \begin{macrocode} \newcommand{\unx@mark}{} \newcommand{\unx@star}{} \newcommand{\unx@empt}{} \edef\unx@mark{?} \edef\unx@star{*} \edef\unx@empt{} % \end{macrocode} % Now we can introduce the main macro. First we open a group % and define |\@tempa| and |\@tempb| to be locally the beginning % of the first arguments. % \begin{macrocode} \newcommand{\unx@parse}[2]{% {% \edef\@tempa{\@car#1\unx@empt\@nil}% \edef\@tempb{\@car#2\unx@empt\@nil}% % \end{macrocode} % Now we test if |\@tempb| is empty. If it is there are two cases % that can be dealt with immediately. % \begin{macrocode} \ifx\@tempb\unx@empt \ifx\@tempa\unx@empt \let\next\@firstoftwo \else \let\next\@secondoftwo \fi % \end{macrocode} % The definition of |\next| will be used after the group as we have % seen above. This is our way to select the third or fourth argument. % % Now assume |\@tempb| is not empty. Then there are three cases. % First it may be ``?'' representing an arbitrary character. % Then |\@tempa| must not be empty. % \begin{macrocode} \else \ifx\@tempb\unx@mark \ifx\@tempa\unx@empt \let\next\@secondoftwo % \end{macrocode} % If |\@tempa| is not empty it is accepted whatever it may be. % Hence we are reduced to compare the rest of the arguments. % \begin{macrocode} \else \edef\next{% \noexpand\IfUnixNameThenElse {\@cdr#1\unx@empt\@nil}{\@cdr#2\unx@empt\@nil}% }% \fi % \end{macrocode} % |\@tempb| may be ``$*$''. Then we have to branch. Any begining of % the first string may be represented by this wildcard. Hence we have % to test whether any ending of it may be represented by the ending % of the second one. The macro |\unx@branch| will do that. % \begin{macrocode} \else \ifx\@tempb\unx@star \edef\next{% \noexpand\unx@branch{#1}{\@cdr#2\unx@empt\@nil}% }% % \end{macrocode} % If |\@tempb| is just a character, we have to get rid of the catcodes. % The reason was explained in the \pkg{email} package. If the % characters agree we have to pass to the endings. Otherwise % the comparison fails. % \begin{macrocode} \else \edef\@tempa{\expandafter\string\csname\@tempa\endcsname}% \edef\@tempb{\expandafter\string\csname\@tempb\endcsname}% \ifx\@tempa\@tempb \edef\next{% \noexpand\unx@parse {\@cdr#1\unx@empt\@nil}{\@cdr#2\unx@empt\@nil}% }% \else \let\next\@secondoftwo \fi \fi \fi \fi % \end{macrocode} % Now we execute |\next|. % \begin{macrocode} \expandafter}\next% } % \end{macrocode} % We come to |\unx@branch|. The idea is very simple. We modify % the last argument in such a way that it will keep on reducing % then first argument and restart testing. It should give up only % when the first argument becomes empty. % \begin{macrocode} \newcommand{\unx@branch}[4]{% \unx@parse{#1}{#2}{#3}{\unx@cont{#1}{#2}{#3}{#4}}% } % \end{macrocode} % This is done in the following obvious way. % \begin{macrocode} \newcommand{\unx@cont}[2]{% {% \def\@tempa{#1}% \ifx\@tempa\unx@empt \let\next\@secondoftwo \else \edef\next{% \noexpand\unx@branch{\@cdr#1\unx@empt\@nil}{#2}% }% \fi \expandafter}\next } % % \end{macrocode} % % \iffalse ********************************************* METACOMMENT % ------------------------------------------------------------------ % \section{Character Table} % \begin{macrocode} %<*installation> \endinput % % \end{macrocode} % ------------------------------------------------------------------ % ********************************************** END METACOMMENT \fi % %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} %% % \Finale