% \iffalse meta-comment % % Copyright (C) 1993-2023 % % The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the Standard LaTeX `Tools Bundle'. % ------------------------------------------------------- % % It may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % The list of all files belonging to the LaTeX `Tools Bundle' is % given in the file `manifest.txt'. % % \fi % \iffalse %% File: tabularx.dtx Copyright (C) 1991-1999 2012 2014 2016 2017 David Carlisle % %<*dtx> \ProvidesFile{tabularx.dtx} % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{tabularx} % \ProvidesFile{tabularx.drv} % \fi % \ProvidesFile{tabularx.dtx} [2023/07/08 v2.11c `tabularx' package (DPC)] % \iffalse %<*driver> \documentclass{ltxdoc} \usepackage[infoshow]{tabularx} \begin{document} \DocInput{tabularx.dtx} \end{document} % % \fi % % \changes{v1.00}{1992/01/30}{Initial version.} % \changes{v1.01}{1992/07/07}{Re-issue for the new doc and docstrip.} % \changes{v1.02}{1992/07/17}{Added some support for \cmd\verb} % \changes{v1.03}{1992/08/17} % {Added \cs{ifnum0}!=`\{\cs{fi}\} brackets after report by % Andreas Maassen} % \changes{v1.04}{1992/09/02} % {fixed \cmd\verb, and support footnotes.} % \changes{v1.05}{1992/11/06} % {preserve all LaTeX counters} % \changes{v1.06}{1993/08/02} % {(Martin Schroeder) Support the optional [t] or [b] argument. % Also now works with delarray.sty.} % \changes{v1.07}{1993/08/27} % {Modifications to make this style compatible with calc.sty.} % \changes{v2.00}{1994/03/14} % {Update to LaTeX2e} % \changes{v2.01}{1994/05/22} % {New Tracing format.} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % \GetFileInfo{tabularx.dtx} % \title{The \textsf{tabularx} package\thanks{This file % has version number \fileversion, last % revised \filedate.}} % \author{David Carlisle} % \date{\filedate} % \MaintainedByLaTeXTeam{tools} % \maketitle % \DeleteShortVerb{\|} % \MakeShortVerb{\"} % % \begin{abstract} % A new environment, {\ttfamily tabularx}, is defined, which takes the % same arguments as {\ttfamily tabular*}, but modifies the widths of % certain columns, rather than the inter column space, to set a table % with the requested total width. The columns that may stretch are % marked with the new token {\ttfamily X} in the preamble argument. % % This package requires the {\ttfamily array} package. % \end{abstract} % % \section{Introduction} % This package implements a version of the {\ttfamily tabular} % environment in which the widths of certain columns are calculated so % that the table is a specified width. Requests for such an % environment seem to occur quite regularly in {\ttfamily % comp.text.tex}. % % \DescribeEnv{tabularx} % "\begin{tabularx}{"\meta{width}"}["\meta{pos}"]{"\meta{preamble}"}"\\ % The arguments of "tabularx" are essentially the same as those of % the standard "tabular*" environment. However rather than adding space % between the columns to achieve the desired width, it adjusts the % widths of some of the columns. The columns which are affected by the % {\ttfamily tabularx} environment should be denoted with the letter % {\ttfamily X} in the preamble argument. The {\ttfamily X} column % specification will be converted to "p{"\meta{some value}"}" once the % correct column width has been calculated. % % \section{Examples} % % The following table is set with % "\begin{tabularx}{250pt}{|c|X|c|X|} ...". % % \begin{center} % \begin{tabularx}{250pt}{|c|X|c|X|} % \hline % \multicolumn{2}{|c|}{Multicolumn entry!}& % THREE& % FOUR\\ % \hline % one& % \raggedright\arraybackslash The width of this column depends on the % width of the table.\footnote % {You can now use {\ttfamily \bslash footnote} inside {\ttfamily % tabularx}!}& % three& % \raggedright\arraybackslash Column four will act in the same way as % column two, with the same width.\\ % \hline % \end{tabularx} % \end{center} % If we change the first line to "\begin{tabularx}{300pt}{|c|X|c|X|}" we % get: % \begin{center} % \begin{tabularx}{300pt}{|c|X|c|X|} % \hline % \multicolumn{2}{|c|}{Multicolumn entry!}& % THREE& % FOUR\\ % \hline % one& % \raggedright\arraybackslash The width of this column depends on the % width of the table.& % three& % \raggedright\arraybackslash Column four will act in the same way as % column two, with the same width.\\ % \hline % \end{tabularx} % \end{center} % % \edef\mytt{\expandafter\noexpand\csname % mdseries\endcsname\noexpand\ttfamily} % \section{Differences between {\mytt tabularx} and {\mytt tabular*}} % These two environments take the same arguments, to produce a table of % a specified width. The main differences between them are: % \begin{itemize} % \item {\ttfamily tabularx} modifies the widths of the \emph{columns}, % whereas {\ttfamily tabular*} modifies the widths of the inter-column % \emph{spaces}. % \item {\ttfamily tabular} and {\ttfamily tabular*} environments may be % nested with no restriction, however if one {\ttfamily tabularx} % environment occurs inside another, then the inner one {\em must\/} be % enclosed by "{ }". % \item The body of the {\ttfamily tabularx} environment is in fact the % argument to a command, and so certain constructions which are not % allowed in command arguments (like "\verb") may not be used.\footnote % {Since Version 1.02, {\ttfamily\bslash verb} and {\ttfamily\bslash % verb*} may be used, but they may treat spaces incorrectly, and the % argument can not contain an unmatched {\ttfamily\char`\{} or % {\ttfamily\char`\}}, or a {\ttfamily\char`\%} character.} % \item {\ttfamily tabular*} uses a primitive capability of \TeX\ to % modify the inter column space of an alignment. {\ttfamily tabularx} % has to set the table several times as it searches for the best column % widths, and is therefore much slower. Also the fact that the body is % expanded several times may break certain \TeX\ constructs. % \end{itemize} % % \section{Customising the behaviour of {\mytt tabularx}} % % \subsection{Terminal output} % \DescribeMacro{\tracingtabularx} % If this declaration is made, say in the document preamble, then all % following {\ttfamily tabularx} environments will print information % about column widths as they repeatedly re-set the tables to find the % correct widths. % % As an alternative to using the "\tracingtabularx" declaration, either % of the options "infoshow" or "debugshow" may be given, either in the % "\usepackage" command that loads "tabularx", or as a global option % in the "\documentclass" command. % % \subsection{The environment used to typeset the {\mytt X} columns} % By default the {\ttfamily X} specification is turned into % "p{"\meta{some value}"}". Such narrow columns often % require a special format, this may be achieved using the ">" syntax % of {\ttfamily array.sty}. So for example you may give a specification % of ">{\small}X". Another format which is useful in narrow columns is % ragged right, however \LaTeX's "\raggedright" macro redefines % "\\" in a way which conflicts with its use in a tabular or array % environments. %\DescribeMacro{\arraybackslash} % For this reason this package introduces the command "\arraybackslash", % this may be used after a "\raggedright", "\raggedleft" or % "\centering" declaration. Thus a {\ttfamily tabularx} preamble may % specify\\ % ">{\raggedright\arraybackslash}X". % % \DescribeMacro{\newcolumntype} % These preamble specifications may of course be saved using the % command "\newcolumntype" defined in {\ttfamily array.sty}. Thus we % may say\\ % "\newcolumntype{Y}{>{\small\raggedright\arraybackslash}X}"\\ % and then use {\ttfamily Y} in the {\ttfamily tabularx} preamble % argument. % % \DescribeMacro{\tabularxcolumn} % The {\ttfamily X} columns are set using the {\ttfamily p} column which % corresponds to "\parbox[t]". You may want them set using, say, the % {\ttfamily m} column, which corresponds to "\parbox[c]". It is not % possible to change the column type using the ">" syntax, so another % system is provided. "\tabularxcolumn" should be defined to be a macro % with one argument, which expands to the {\ttfamily tabular} preamble % specification that you want to correspond to {\ttfamily X}. The % argument will be replaced by the calculated width of a column. % % The default is "\newcommand{\tabularxcolumn}[1]{p{#1}}". So we may % change this with a command such as:\\ % "\renewcommand{\tabularxcolumn}[1]{>{\small}m{#1}}" % % \subsection{Column widths} % Normally all {\ttfamily X} columns in a single table are set to the % same width, however it is possible to make {\ttfamily tabularx} set % them to different widths. % A preamble argument of % "{>{\hsize=.5\hsize\linewidth=\hsize}X"\\ % " >{\hsize=1.5\hsize\linewidth=\hsize}X}"\\ % specifies two columns, the second will be three times as wide as the % first. However if you want to play games like this you should follow % the following two rules. % \begin{itemize} % \item Make sure that the sum of the widths of all the {\ttfamily X} % columns is unchanged. (In the above example, the new widths still add % up to twice the default width, the same as two standard {\ttfamily X} % columns.) % \item Do not use "\multicolumn" entries which cross any {\ttfamily X} % column. % \end{itemize} % As with most rules, these may be broken if you know what you are % doing. % % \subsection{If the algorithm fails\ldots} % It may be that the widths of the `normal' columns of the table % already total more than the requested total % width. \textsf{tabularx} refuses to set the % \texttt{X} columns to a negative width, so in this case you get a % warning ``X Columns too narrow (table too wide)''. % % The \texttt{X} columns will in this case be set to a width of 1em % and so the table itself will be wider than the requested total width % given in the argument to the environment. % This behaviour of the package can be customised slightly % as noted in the documentation of the code section. % % \MaybeStop{} % % \section{The Macros} % % \begin{macrocode} %<*package> % \end{macrocode} % % \changes{v2.00}{1994/02/07} % {New Option Handling} % \begin{macrocode} \DeclareOption{infoshow}{\AtEndOfPackage\tracingtabularx} \DeclareOption{debugshow}{\AtEndOfPackage\tracingtabularx} \ProcessOptions % \end{macrocode} % % This requires {\ttfamily array.sty}. % \changes{v2.00}{1994/02/07} % {Use LaTeX2e's \cmd{\RequirePackage} to load array} % \begin{macrocode} \RequirePackage{array}[1994/02/03] % \end{macrocode} % % First some registers etc.\ that we need. % \begin{macrocode} \newdimen\TX@col@width \newdimen\TX@old@table \newdimen\TX@old@col \newdimen\TX@target \newdimen\TX@delta \newcount\TX@cols \newif\ifTX@ % \end{macrocode} % % Now a trick to get the body of an environment into a token register, % without doing any expansion. This does not do any real checking of % nested environments, so if you should need to nest one {\ttfamily % tabularx} inside another, the inner one must be surrounded by "{ }". % % \begin{macro}{\tabularx} % Prior to v1.06, this macro took two arguments, which were saved in % separate registers before the table body was saved by "\TX@get@body". % Unfortunately this disables the "[t]" optional argument. Now just save % the width specification separately, then clear the token register % "\toks@". % Finally call "\TX@get@body" to begin saving the body of the table. % The "{\ifnum0=`}\fi" was added at v1.03, to allow "tabularx" to appear % inside a "\halign".^^A % \setbox0=\hbox{\footnotesize"\iffalse{\fi\ifnum0=`}\fi"}^^A % \setbox2=\hbox{\footnotesize"\ifnum0=`{}\fi"}^^A % \footnote{This adds an extra level of grouping, % which is not really needed. Instead, I could use \box0\ here, and % \box2\ below, however the code here would then have to be moved after % the first line, because of the footnote to page 386 of the \TeX{}book, % and I do not think I should be writing code that is so obscure as to % be documented in a footnote in an appendix called ``Dirty Tricks''!} % % This mechanism of grabbing an environment body does have the % disadvantage (shared with the AMS alignment environments) that you % can not make extension environments by code such as %\begin{verbatim} %\newenvironment{foo}{\begin{tabularx}{XX}}{\end{tabularx}} %\end{verbatim} % as the code is looking for a literal string "\end{tabularx}" to stop % scanning. Since version 2.02, one may avoid this problem by using % "\tabularx" and "\endtabularx" directly in the definition: %\begin{verbatim} %\newenvironment{foo}{\tabularx{XX}}{\endtabularx} %\end{verbatim} % The scanner now looks for the end of the current environment ("foo" in % this example). There are some restrictions on this usage, the % principal one being that "\endtabularx" must not be inside any "{ }" pairs, % so that the code before "\endtabularx" may be extracted and added to the table body % (prior to version 2.09 "\endtabularx" had to be % the \emph{first} token of the `end code' of the environment). % \begin{macrocode} \def\tabularx#1{% % \end{macrocode} % \changes{v2.02}{1995/03/20} % {New local setting of \cs{TX@}} % \changes{v2.09}{1998/05/13} % {Use \cs{setlength}, so that calc extensions apply. tools/2793} % \changes{v2.11c}{2020/01/15}{Delete duplicated . at end of message} % Allow "\tabularx" "\endtabularx" (but not "\begin{tabularx}" % "\end{tabularx}") to be used in "\newenvironment" definitions. % \begin{macrocode} \edef\TX@{\@currenvir}% {\ifnum0=`}\fi % \end{macrocode} % "\relax" added at v1.05 so that non-expandable length tokens, like % "\textwidth" do not generate an extra space, and an overfull box. % "\relax" removed again at v2.09 in favour of "\setlength" so if you % use the calc package you can use a width of "(\textwidth-12pt)/2". % \begin{macrocode} \setlength\TX@target{#1}% \TX@typeout{Target width: #1 = \the\TX@target}% \toks@{}\TX@get@body} % \end{macrocode} % \end{macro} % % \begin{macro}{\endtabularx} % This does not do very much\ldots % \changes{v2.02}{1995/03/20} % {Macro added} % \begin{macrocode} \let\endtabularx\relax % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@get@body} % Place all tokens as far as the first "\end" into a token register. % Then call "\TX@find@end" to see if we are at "\end{tabularx}". % \begin{macrocode} \long\def\TX@get@body#1\end {\toks@\expandafter{\the\toks@#1}\TX@find@end} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@find@end} % If we are at "\end{tabularx}", call "\TX@endtabularx", otherwise % add "\end{...}" to the register, and call "\TX@get@body" again. % \begin{macrocode} \def\TX@find@end#1{% \def\@tempa{#1}% \ifx\@tempa\TX@\expandafter\TX@endtabularx \else\toks@\expandafter {\the\toks@\end{#1}}\expandafter\TX@get@body\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@find@endtabularxa} % \changes{v2.09}{2014/04/22}{macro added} % \changes{v2.10}{2014/05/13}{macro modified to test for missing \cs{endtabularx}} % \changes{v2.11}{2016/01/03}{Fix to previous change to guard against empty arg 2. (Ulrike Fischer)} % Split up the end code, and extract the part that lives in the table body. % \begin{macrocode} \long\def\TX@find@endtabularxa #1\endtabularx#2\endtabularx#3\TX@find@endtabularxa{% \ifx\TX@#2\relax\else \toks@\expandafter{\the\toks@#1}% \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\TX@find@endtabularxb} % \changes{v2.09}{2014/04/22}{macro added} % \changes{v2.10}{2014/05/13}{macro modified to test for missing \cs{endtabularx}} % Split up the end code, and extract the part that lives outside the table body. % \begin{macrocode} \long\def\TX@find@endtabularxb #1\endtabularx#2\endtabularx#3\TX@find@endtabularxb{% \ifx\TX@#2% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi {#1}{#2}} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@find@endtabularxbb} % \changes{v2.10}{2014/05/13}{macro added} % Helper to avoid needing 15 consecutive "expandafter" % \begin{macrocode} \def\TX@find@endtabularxbb{% \expandafter\expandafter\expandafter \TX@find@endtabularxb } % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@} % The string {\ttfamily tabularx} as a macro for testing with "\ifx". % \begin{macrocode} \def\TX@{tabularx} % \end{macrocode} % \end{macro} % % Now that all the parts of the table specification are stored in % registers, we can begin the work of setting the table. % % The algorithm for finding the correct column widths is as follows. % Firstly set the table with each {\ttfamily X} column the width of the % final table. Assuming that there is at least one {\ttfamily X} column, % this will produce a table that is too wide. Divide the excess width by % the number of {\ttfamily X} columns, and reduce the column width by % this amount. Reset the table. If the table is not now the correct % width, a "\multicolumn" entry must be `hiding' one of the {\ttfamily % X} columns, and so there is one less {\ttfamily X} column affecting % the width of the table. So we reduce by 1 the number of X columns and % repeat the process. % % \begin{macro}{\TX@endtabularx} % Although I have tried to make {\ttfamily tabularx} look like an % environment, it is in fact a command, all the work is done by this % macro. % \begin{macrocode} \def\TX@endtabularx{% % \end{macrocode} % \changes{v2.09}{2014/04/22}{call to \cs{TX@find@endtabularxa} added} % \changes{v2.10}{2014/05/13}{macro modified to test for missing \cs{endtabularx}} % \begin{macrocode} \expandafter\expandafter\expandafter \TX@find@endtabularxa\csname end\TX@\endcsname \endtabularx\TX@\endtabularx\TX@find@endtabularxa % \end{macrocode} % Define the {\ttfamily X} column, with an internal version of the % "\newcolumntype" command. The "\expandafter" commands enable % "\NC@newcol" to get the {\em expansion} of\\ % "\tabularxcolumn{\TX@col@width}" as its % argument. This will be the definition of an {\ttfamily X} column, as % discussed in section 4. % \begin{macrocode} \expandafter\TX@newcol\expandafter{\tabularxcolumn{\TX@col@width}}% % \end{macrocode} % Initialise the column width, and the number of {\ttfamily X} columns. % The number of {\ttfamily X} columns is set to one, which means that % the initial count will be one too high, but this value is decremented % before it is used in the main loop. % % Since v1.02, switch the definition of "\verb". % \begin{macrocode} \let\verb\TX@verb % \end{macrocode} % Since v1.05, save the values of all \LaTeX\ counters, the list % "\cl@@ckpt" contains the names of all the \LaTeX\ counters that have % been defined so far. We expand "\setcounter" at this point, as it % results in fewer tokens being stored in "\TX@ckpt", but the actual % resetting of the counters occurs when "\TX@ckpt" is expanded after % each trial run. % Actually since v1.07, use something equivalent to the expansion of the % original definition of "\setcounter", so that "tabularx" works in % conjunction with "calc.sty". % \begin{macrocode} \def\@elt##1{\global\value{##1}\the\value{##1}\relax}% \edef\TX@ckpt{\cl@@ckpt}% \let\@elt\relax \TX@old@table\maxdimen \TX@col@width\TX@target \global\TX@cols\@ne % \end{macrocode} % Type out some headings (unless this is disabled). % \begin{macrocode} \TX@typeout@ {\@spaces Table Width\@spaces Column Width\@spaces X Columns}% % \end{macrocode}% % First attempt. Modify the {\ttfamily X} definition to count {\ttfamily % X} columns. % \begin{macrocode} \TX@trial{\def\NC@rewrite@X{% \global\advance\TX@cols\@ne\NC@find p{\TX@col@width}}}% % \end{macrocode} % Repeatedly decrease column width until table is the correct width, % or stops shrinking, or the columns become too narrow. % If there are no multicolumn entries, this will only take one attempt. % \begin{macrocode} \loop \TX@arith \ifTX@ \TX@trial{}% \repeat % \end{macrocode} % One last time, with warnings back on (see appendix D) % use {\ttfamily tabular*} to put it in a box of the right size, in case % the algorithm failed to find the correct size. % % Since v1.04, locally make "\footnotetext" save its argument in a token % register. % Since v1.06, "\toks@" contains the preamble specification, % and possible optional argument, as well as the table body. % \begin{macrocode} {\let\@footnotetext\TX@ftntext\let\@xfootnotenext\TX@xftntext \csname tabular*\expandafter\endcsname\expandafter\TX@target \the\toks@ \csname endtabular*\endcsname}% % \end{macrocode} % Now the alignment is finished, and the "}" has restored the original % meaning of "\@footnotetext" expand the register "\TX@ftn" which will % execute a series of\\ % "\footnotetext["\meta{num}"]{"\meta{note}"}"\\ % commands. We need to be careful about clearing the register as we may % be inside a nested {\ttfamily tabularx}. % \begin{macrocode} \global\TX@ftn\expandafter{\expandafter}\the\TX@ftn % \end{macrocode} % Now finish off the {\ttfamily tabularx} environment. Note that we need % "\end{tabularx}" here as the "\end{tabularx}" in the user's % file is never expanded. Now use "\TX@" rather than "tabularx". % \changes{v2.02}{1995/03/20} % {Close the environment \cs{TX@} rather than `tabularx'} % % We also need to finish off the group started by "{\ifnum0=`}\fi" in % the macro "\tabularx". % \begin{macrocode} \ifnum0=`{\fi}% % \end{macrocode} % \changes{v2.09}{2014/04/22}{call to \cs{TX@find@endtabularxb} added} % \changes{v2.10}{2014/05/13}{macro modified to test for missing \cs{endtabularx}} % \begin{macrocode} \expandafter\expandafter\expandafter \TX@find@endtabularxbb \expandafter\end\expandafter{\TX@}% \endtabularx\TX@\endtabularx\TX@find@endtabularxb } % \end{macrocode} % \end{macro} % % % \begin{macro}{\TX@arith} % Calculate the column width for the next try, setting the flag % "\ifTX@" to false if the loop should be aborted. % \begin{macrocode} \def\TX@arith{% \TX@false % \end{macrocode} % \changes{v2.08}{2012/02/06}{Avoid exceeding maxdimen during trials} % \begin{macrocode} \@tempdimb\maxdimen \divide\@tempdimb\TX@cols \ifdim\TX@col@width>\@tempdimb \TX@typeout@{Don't exceed \maxdimen}% \wd\@tempboxa\maxdimen \fi \ifdim\TX@old@table=\wd\@tempboxa % \end{macrocode} % If we have reduced the column width, but the table width has not % changed, we stop the loop, and output the table (which will cause an % over-full alignment) with the previous value of "\TX@col@width". % \begin{macrocode} \TX@col@width\TX@old@col \TX@typeout@{Reached minimum width, backing up.}% \else % \end{macrocode} % Otherwise calculate the amount by which the current table is too wide. % \begin{macrocode} \dimen@\wd\@tempboxa \advance\dimen@ -\TX@target \ifdim\dimen@<\TX@delta % \end{macrocode} % If this amount is less than "\TX@delta", stop. ("\TX@delta" % should be non-zero, otherwise we may miss the target due to rounding % error.) % \begin{macrocode} \TX@typeout@{Reached target.}% \else % \end{macrocode} % Reduce the number of effective {\ttfamily X} columns by one. (Checking % that we do not get 0, as this would produce an error later.) Then % divide excess width by the number of effective columns, and calculate % the new column width. Temporarily store this value (times $-1$) in % "\dimen@". % \begin{macrocode} \ifnum\TX@cols>\@ne \advance\TX@cols\m@ne \fi \divide\dimen@\TX@cols \advance\dimen@ -\TX@col@width \ifdim \dimen@ >\z@ % \end{macrocode} % If the new width would be too narrow, abort the loop. At the moment % too narrow means less than 0\,pt! % % Prior to v2.03, if the loop was aborted here, the X columns were left % with the width of the previous run, but this may make the table far % too wide as initial guesses are always too big. Now force to % "\TX@error@width" which defaults to be 1em. If you want to % get the old behaviour stick\\ % "\renewcommand\TX@error@width{\TX@col@width}"\\ % in a package file loaded after \textsf{tabularx}. % \changes{v2.03}{1997/02/20}{Improve warning message and force to 1em.} % \begin{macrocode} \PackageWarning{tabularx}% {X Columns too narrow (table too wide)\MessageBreak}% \TX@col@width\TX@error@width\relax \else % \end{macrocode} % Otherwise save the old settings, and set the new column width. Set the % flag to true so that the table will be set, and the loop will be % executed again. % \begin{macrocode} \TX@old@col\TX@col@width \TX@old@table\wd\@tempboxa \TX@col@width-\dimen@ \TX@true \fi \fi \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@error@width} % \changes{v2.03}{1997/02/20}{macro added.} % \changes{v2.04}{1997/02/26}{spurious brace removed.} % If the calculated width is negative, use this instead. % \begin{macrocode} \def\TX@error@width{1em} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@delta} % Accept a table that is within "\hfuzz" of the correct width. % \begin{macrocode} \TX@delta\hfuzz % \end{macrocode} % \end{macro} % % Initialise the {\ttfamily X} column. The definition can be empty here, % as it is set for each {\ttfamily tabularx} environment. % \begin{macrocode} \newcolumntype{X}{} % \end{macrocode} % % \begin{macro}{\tabularxcolumn} % The default definition of {\ttfamily X} is "p{#1}". % \begin{macrocode} \def\tabularxcolumn#1{p{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@newcol} % A little macro just used to cut down the number of "\expandafter" % commands needed. % \begin{macrocode} \def\TX@newcol{\newcol@{X}[0]} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@trial} % Make a test run. % \begin{macrocode} \def\TX@trial#1{% \setbox\@tempboxa\hbox{% % \end{macrocode} % Any extra commands. This is used on the first run to count the number % of {\ttfamily X} columns. % \begin{macrocode} #1\relax % \end{macrocode} % Since v1.04, make "\footnotetext" gobble its arguments. Also locally % clear "\TX@vwarn" so that the warning is generated by the {\ttfamily % final} run, and does not appear in the middle of the table if % "\tracingtabularx". % \begin{macrocode} \let\@footnotetext\TX@trial@ftn \let\TX@vwarn\@empty % \end{macrocode} % Do not nest {\ttfamily tabularx} environments during trial runs. This % would waste time, and the global setting of "\TX@cols" would break the % algorithm. % \begin{macrocode} \expandafter\let\expandafter\tabularx\csname tabular*\endcsname \expandafter\let\expandafter\endtabularx\csname endtabular*\endcsname % \end{macrocode} % Added at v1.05: disable "\write"s during a trial run. This trick is % from the \TeX{}book.\footnote{Actually the \TeX{}book trick does % not work correctly, so changed for v2.05.} % \changes{v2.05}{1997/09/18} % {New \cs{write} trick. tools/2607} % \changes{v2.07}{1999/01/07} % {Newer \cs{write} trick. tools/2792} % \begin{macrocode} \def\write{\begingroup \def\let{\afterassignment\endgroup\toks@}% \afterassignment\let\count@}% % \end{macrocode} % Turn off warnings (see appendix D). Also prevent them being turned % back on by setting the parameter names to be registers. % \begin{macrocode} \hbadness\@M \hfuzz\maxdimen \let\hbadness\@tempcnta \let\hfuzz\@tempdima % \end{macrocode} % Make the table, and finish the hbox. % Since v1.06, "\toks@" contains the preamble specification, % and possible optional argument, as well as the table body. % \begin{macrocode} \expandafter\tabular\the\toks@ \endtabular}% % \end{macrocode} % Since v1.05 reset all \LaTeX\ counters, by executing "\TX@ckpt". % \begin{macrocode} \TX@ckpt % \end{macrocode} % Print some statistics. % Added "\TX@align" in v1.05, to line up the columns. % \begin{macrocode} \TX@typeout@{\@spaces \expandafter\TX@align \the\wd\@tempboxa\space\space\space\space\space\@@ \expandafter\TX@align \the\TX@col@width\space\space\space\space\space\@@ \@spaces\the\TX@cols}} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@align} % Macro added at v1.05, to improve the printing of the tracing info. % \begin{macrocode} \def\TX@align#1.#2#3#4#5#6#7#8#9\@@{% \ifnum#1<10 \space\fi \ifnum#1<100 \space\fi \ifnum#1<\@m\space\fi \ifnum#1<\@M\space\fi #1.#2#3#4#5#6#7#8\space\space} % \end{macrocode} % \end{macro} % % \begin{macro}{\arraybackslash} % "\\" hack. % \changes{v2.08}{2012/02/06}{Don't define this if already defined by newer array package and use tabularnewline now this is in 2e.} % \begin{macrocode} \ifx\arraybackslash\@undefined \def\arraybackslash{\let\\\tabularnewline} \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\tracingtabularx} % Print statistics on column and table widths. % \begin{macrocode} \def\tracingtabularx{% \def\TX@typeout{\PackageWarningNoLine{tabularx}}% \def\TX@typeout@##1{\typeout{(tabularx) ##1}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@typeout} % The default is to be quiet. % \begin{macrocode} \let\TX@typeout\@gobble \let\TX@typeout@\@gobble % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@ftn} % A token register for saving footnote texts. % \begin{macrocode} \newtoks\TX@ftn % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@ftntext} % \begin{macro}{\TX@xftntext} % Inside the alignment just save up the footnote text in a token % register. % \begin{macrocode} \long\def\TX@ftntext#1{% \edef\@tempa{\the\TX@ftn\noexpand\footnotetext [\the\csname c@\@mpfn\endcsname]}% \global\TX@ftn\expandafter{\@tempa{#1}}}% \long\def\TX@xftntext[#1]#2{% \global\TX@ftn\expandafter{\the\TX@ftn\footnotetext[#1]{#2}}} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\TX@trial@ftn} % On trial runs, gobble footnote texts. % \begin{macrocode} \long\def\TX@trial@ftn#1{} % \end{macrocode} % \end{macro} % % This last section was added at Version 1.02. Previous versions % documented the fact that "\verb" did not work inside {\ttfamily % tabularx}, but that did not stop people using it! This usually put % \LaTeX\ into an irrecoverable error position, with error messages that % did not mention the cause of the error. The `poor man's "\verb"' (and % "\verb*") defined here is based on page 382 of the \TeX{}book. As % explained there, doing verbatim this way means that spaces are not % treated correctly, and so "\verb*" may well be useless, however I % consider this section of code to be error-recovery, rather than a real % implementation of verbatim. % % The mechanism is quite general, and any macro which wants to allow a % form of "\verb" to be used within its argument may % "\let\verb=\TX@verb". (Making sure to restore the real definition % later!) % % "\verb" and "\verb*" are subject to the following restrictions: % \begin{enumerate} % \item Spaces in the argument are not read verbatim, but may be skipped % according to \TeX's usual rules. % \item Spaces will be added to the output after control words, even if % they were not present in the input. % \item Unless the argument is a single space, any trailing space, % whether in the original argument, or added as in (2), % will be omitted. % \item The argument must not end with "\", so "\verb|\|" is not % allowed, however, because of (3), "\verb|\ |" produces % "\". % \item The argument must be balanced with respect to "{" and "}". So % "\verb|{|" is not allowed. % \item A comment character like "%" will not appear verbatim. It will % act as usual, commenting out the rest of the input line! % \item The combinations "?`" and "!`" will appear as % {\ttfamily?`} and {\ttfamily!`} if the {\ttfamily cmtt} font is % being used. % \end{enumerate} % % \begin{macro}{\TX@verb} % The internal definition of "\verb". Spaces will be replaced by "~", so % for the star-form, "\let" "~" be \verb*| |, which we obtain as % "\uppercase{*}". Use "{\ifnum0=`}\fi" rather than "\bgroup" to allow % "&" to appear in the argument. % \begin{macrocode} {\uccode`\*=`\ % \uppercase{\gdef\TX@verb{% \leavevmode\null\TX@vwarn {\ifnum0=`}\fi\ttfamily\let\\\ignorespaces \@ifstar{\let~*\TX@vb}{\TX@vb}}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@vb} % Get the `almost verbatim' text using "\meaning". The `"!"' is added to % the front of the user supplied text, to ensure that the whole argument % does not consist of a single "{ }" group. \TeX\ would strip the outer % braces from such a group. The `"!"' will be removed later. % % Originally I followed Knuth, and had "\def\@tempa{##1}", however, this % did not allow "#" to appear in the argument. So in v1.04, I changed % this to use a token register, and "\edef". This allows "#" to appear % but makes each one appear twice, so later we loop through, replacing % "##" by "#". % \begin{macrocode} \def\TX@vb#1{\def\@tempa##1#1{\toks@{##1}\edef\@tempa{\the\toks@}% \expandafter\TX@v\meaning\@tempa\\ \\\ifnum0=`{\fi}}\@tempa!} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@v} % Strip the initial segment of the "\meaning", including the `"!"' % added earlier. % \begin{macrocode} \def\TX@v#1!{\afterassignment\TX@vfirst\let\@tempa= } % \end{macrocode} % \end{macro} % % As explained above we are going to replace "##" pairs by "#". To do % this we need non-special "#" tokens. Make "*" into a parameter % token so that we can define macros with arguments. The normal meanings % will be restored by the "\endgroup" later. % \begin{macrocode} \begingroup \catcode`\*=\catcode`\# \catcode`\#=12 % \end{macrocode} % % \begin{macro}{\TX@vfirst} % As a special case, prevent the first character from being dropped. % This makes "\verb*| |" produce \verb*| |. Then call "\TX@v@". % This is slightly tricky since v1.04, as I have to ensure that an % actual "#" rather than a command "\let" to "#" is passed on if the % first character is "#". % \begin{macrocode} \gdef\TX@vfirst{% \if\@tempa#% \def\@tempb{\TX@v@#}% \else \let\@tempb\TX@v@ \if\@tempa\space~\else\@tempa\fi \fi \@tempb} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@v@} % Loop through the "\meaning", replacing all spaces by "~". If the last % character is a space it is dropped, so that "\verb*|\LaTeX|" produces % "\LaTeX" not \verb*|\LaTeX |. The rewritten tokens are then further % processed to replace "##" pairs. % \begin{macrocode} \gdef\TX@v@*1 *2{% \TX@v@hash*1##\relax\if*2\\\else~\expandafter\TX@v@\fi*2} % \end{macrocode} % \end{macro} % % \begin{macro}{\TX@v@hash} % The inner loop, replacing "##" by "#". % \begin{macrocode} \gdef\TX@v@hash*1##*2{*1\ifx*2\relax\else#\expandafter\TX@v@hash\fi*2} % \end{macrocode} % \end{macro} % % As promised, we now restore the normal meanings of "#" and "*". % \begin{macrocode} \endgroup % \end{macrocode} % % \begin{macro}{\TX@vwarn} % Warn the user the first time this "\verb" is used. % \begin{macrocode} \def\TX@vwarn{% \@warning{\noexpand\verb may be unreliable inside tabularx}% \global\let\TX@vwarn\@empty} % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \Finale \endinput