diff options
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/widetable/widetable.dtx | 428 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/widetable/widetable.ins | 67 |
2 files changed, 495 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/widetable/widetable.dtx b/Master/texmf-dist/source/latex/widetable/widetable.dtx new file mode 100644 index 00000000000..fdd228ef240 --- /dev/null +++ b/Master/texmf-dist/source/latex/widetable/widetable.dtx @@ -0,0 +1,428 @@ +% \iffalse +%% +%% File `widetable.dtx'. +%% Copyright (C) 2009 Claudio Beccari all rights reserved. +%% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{widetable.dtx}% +%</driver> +%<package>\NeedsTeXFormat{LaTeX2e}[2005/12/01] +%<package>\ProvidesPackage{widetable}% +%<*package> + [2009/07/21 v.1.0 Package for typesetting specified width tables] +%</package> +%<*driver> +\documentclass{ltxdoc} +\hfuzz 10pt +\def\prog#1{\textsf{\slshape#1}} +\usepackage{multicol} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{textcomp} +\usepackage{lmodern} +\usepackage[italian,english]{babel} +\begin{document} +\makeatletter +\GetFileInfo{widetable.dtx}% +\title{The Package \textsf{widetable}\thanks{Version number \fileversion; last revision +\filedate.}} +\author{Claudio Beccari} + \maketitle +\begin{multicols}{2} + \tableofcontents + \end{multicols} + \DocInput{widetable.dtx} +\end{document} +%</driver> +% \fi +% \CheckSum{222} +% \begin{abstract} +% This package allows to typeset tables of specified width, provided they fit in one +% page. Instead of introducing an infinite stretching glue, which has an +% unsymmetrical effect in standard \LaTeX, here the |\tabcolsep| dimension is +% computed so as to have the table come out with the proper width. +% \end{abstract} +% +%\section{Introduction} +% It is well known that when the standard environment |tabular*| is opened with +% a specified width, it is necessary to introduce in the delimiter declaration |@{...}| +% of (possibly) the first cell of the model row a declaration such as +% \begin{verbatim} +% \extraclosep{\fill} +% \end{verbatim} +% in addition to other possible printable delimiters, such as vertical lines, and +% other fixed spacing commands. The effect is that the extra stretchable glue +% operates only on the left of each cell \emph{after} (to the \emph{right} of) +% the cell that received the declaration; the first cell will never get larger +% in spite of the presence of this glue. +% +% Another package, |tabularX|, normally distributed by the \LaTeX\,3 Team with +% every version of the \TeX\ system distribution, allows to create expandable cells, +% provided they contain only text. These expandable cells are identified with the +% column identifier |X|; this identifier defines a paragraph-like cell, the width of +% which gets determined after some runs of the typesetter on the same source +% tabular material, so as to find out the correct width of the textual columns. +% +% The approach here is a little bit different: the cell contents need not be textual +% and no cell width is determined in one or more runs of the typesetter; instead the +% inter column glue is determined so as to fill every cell on both sides with the +% proper space. The macros contained in this package are insensitive to the +% particular kind of cell descriptors and to the presence of multiple |\multicolumn| +% commands. It proved to work properly also if the |array| package extensions are +% used. +% +% On the other hand, as well as for |tabularX|, it needs to typeset the table three +% times; the first two times with standard values for the inter column glue +% |\tabcolsep|, in order to find the exact parameters of the linear dependence of +% the table width from the value of that glue; then executes some computations +% so as to extrapolate the final correct value of |\tabcolsep|, and on the third run +% it eventually typesets the table with the specified width. +% +% The time increase needed for these three table typesettings are in general rather +% negligible, nevertheless if a specific document contained many dozens of such +% tables, the compilation time might become observable. +% +% It might be noticed that in order to perform the necessary computations a +% fractional division algorithm had to be implemented; A specific \LaTeX\ run that +% loads several different packages might then contain several fractional division +% macros, besides those already contained in the kernel. But unfortunately each of +% these macros has been designed for a specific purpose and a specific interface. +% +% \section{Usage} +% This package issues an error message only in case the environment includes +% other unhided environment; this is explained in the Implementation section. +% Here it is assumed that the table is first typeset to its +% natural width; should it appear too small, and should it be typeset at a larger +% width, for example by filling the total |\linewidth| available at that specific +% point, then and only then the |tabular| environment is changed to |widetable|, +% Should the initial table be moderately larger than the |\linewidth|, than it might +% be shrinked to |\linewidth| with |widetable|, provided there are enough +% columns, and therefore delimiters, to be reduced in size. Of course it's impossible +% to typeset any table with any negative value of |\tabcolsep|; or better, it is +% possible, but the result in general is very messy. +% +% In other words |widetable| should be used as a second resort, so as to correct +% some typesetting features not considered aesthetically acceptable. +% +% The syntax for the use of the environment |widetable| is the same as that of the +% |tabular*| environment; the only difference is the name. Therefore one has to +% specify: +% \begin{flushleft}\obeylines% +% \cs{begin}\texttt{\{widetable\}\{}\meta{width}\texttt{\}\{}\meta{column descriptors}\texttt{\}} +% \meta{line of cells}\texttt{\cs{\textbackslash}} +% \meta{line of cells}\texttt{\cs{\textbackslash}} +% \texttt{...} +% \meta{line of cells}\texttt{\cs{\textbackslash}} +% \meta{line of cells}\texttt{\cs{\textbackslash}} +% \cs{end}\texttt{\{widetable\}} +% \end{flushleft} +% +% \section{The method} +% The principle on which this little package is based is the following; suppose a +% certain table is typeset with an inter column glue $t_0=0$ and that its width +% turns out to be $l_0$; suppose the same tabular material is typeset again with an +% inter column glue $t_1 >0$ so that the table table gets as large as $l_1>l_0$. +% Then, if the table has to be as wide as $l$ the inter column glue must equal the +% value +% \[ +% t = \frac{l - l_0}{l_1 - l_0}\cdot t_1 +% \] +% Therefore we need to run the typesetting of the same tabular material with the +% two values of the inter column glue set to zero and to $t_1$, respectively, so as +% to find the widths $l_0$ and $l_1$. Afterwards it has to determine the correct +% final value $t$, and typeset once again the same tabular material for the last +% time. +% Of course the first two runs must put their results into suitable boxes so as to +% avoid outputting them into the output file, while at the same time allowing +% to record the width of the enclosing boxes. +% +% \section{The long division algorithm} +% The only simple equation the algorithm must compute consists in evaluating the +% difference of of two lengths (a computation that is perfectly feasible with the +% available simple \TeX\ primitive commands); a fractional division (not feasible +% with any \TeX\ primitive command), and finally into multiplying this division +% result by the only non zero inter column glue (another simple task to be done +% with \TeX\ primitive commands). +% +% I have tried several algorithms for computing the fractional result of the division +% of two lengths; unfortunately no one guarantees a minimum of precision with +% any sized operands; overflows and similar ``accidents'' are very common. +% Iterative algorithms are difficult to initialize; scaling the operands give a good +% % chance of getting acceptable results, but in one way or another I always found +% some drawbacks. +% Therefore I decided to program the so called ``long division'' algorithm +% preceded by a number of tests in order to avoid spending time in vanishing +% results, and, even more important, to waste time in getting overflows that cause +% an abnormal termination of the typesetting program. +% +% Of course there is no limit to a better solution; nevertheless the one I +% implemented never crashed in any real world situation I tested. +% +% \section{Acknowledgements} +% I must deeply thank Enrico Gregorio for the revision of this package macros and +% for his wise suggestions about the correct programming style. If some glitch still +% remains in the programming style, that is just my fault. +% \StopEventually{} +% +% \section{Implementation} +% the first thing to do is to globally define a certain number of \TeX\ dimensions +% and counters; these dimension and counter registers are selected among the +% first even numbered ones, as our Grand Wizard suggested in the \TeX\-book. +% +% Actually I'd prefer to define such registers within the group of the division +% algorithm, so as not to mess up anything that might be used by other macros, +% but I accepted the suggestion of Enrico Gregorio, about the programming style +% and I left these register definitions in a global position, instead of a local group +% position. +% +% Another point that initially I had solved in a different way was to use register +% numbers over the value 255, the maximum that good old \TeX\ could handle. +% Now the typesetting\slash interpreter program \textsf{pdftex} embeds all the +% extensions introduced with the former \textsf{$\varepsilon$-\TeX} program; +% now the numbering of the registers can go up to $2^{15}-1$, and there is +% enough choice for any numbering. But it may be argued that \LaTeX\ users do +% not upgrade their software so often, while there are some situations where the +% use of obsolete versions must be still preferred (I can't imagine any, but they +% assure me that there are some). Therefore Enrico correctly suggests to use the +% scratch even numbered registers (Knuth's suggestion, although Knuth excluded +% the counter registers from this statement, being the first 10 counters reserved +% for complicated page numbering applications). +% \begin{macrocode} +\dimendef\wt@Numer=2 +\dimendef\wt@Denom=4 +\countdef\wt@Num=2 +\countdef\wt@Den=4 +\countdef\wt@I=6 +\def\wt@segno{} +% \end{macrocode} +% +% We then start the definition of the division algorithm; the name of the macro and +% the separators of the delimited arguments are in Italian, thus minimizing the risk +% of colliding with macros of other packages. ``dividi\dots per\dots in\dots'' +% means ``divide\dots by\dots, to\dots''; the first ``\dots'' represent the +% dividend, the second ``dots'' represent the divisor (both are lengths), while the +% third ``\dots'' represent the quotient (a signed fractional decimal number). +% +% The first operations performed on the operands are to copy them into named +% dimension registers; the named registers make the programming a little easier, +% in the sense that the chosen names have a meaning and their contents should +% conform to that meaning. +% +% Then the sings of the register operands are checked and pssibly changed so as to +% work with positive values; the overall result sign is memorized into a named +% macro (all macros are named, but here the name conforms to its contents +% ``segno'' maps to ``sign''). +% Afterwards the zero value of the denominator is tested; if the test is true the +% result assigned to the internal quotient macro |\wt@Q| is the signed dimensional +% ``infiniy'', that in \TeX\ and \LaTeX\ is equal to $2^{30}-1$ scaled points; this +% value is assigned by the format to the kernel dimension register |\maxdimen|, so +% we need just use this name, instead of assigning strange numerical values; the +% only thing we must pay attention to is to strip the ``pt'' information from this +% ``infinite'' dimension, since the quotient must be a dimensionless signed +% fractional decimal number. +% +% Otherwise we load the operands in similarly named counter registers, effectively +% transferring the dimension integer number of scaled points to integer variables +% over which we continue our operations. +% +% We compute by the primitive \TeX\ integer division command the integer part of +% the quotient and we assing its expanded decimal value, followed by a decimal +% point, to the temporary internal quotient. Getting back to dimensions, +% we compute the remainder of the numerator minus the quotient times the +% denominator in terms of lengths. We locally set the number of iterations |\wt@I| +% to six, and then we call the iterative algorithm of the long division within a +% |\@whilenum|\dots|\do| cycle. +% +% At the exit of this cycle the internal quotient |\wt@Q| contains all the digits of the +% integer and the fractional part of the result. +% +% Now comes the interesting part: we are within a group and we must ``throw'' +% the quotient outside the group, but hopefully we would not like to leave +% something behind; we then define an expanded macro that contains the +% unexpanded |\endgroup| so that when we execute that macro, it is this very +% action that closes the group and at the same time, in spite of having been started +% within it, +% it keeps being executed bringing outside the definition of the external quotient +% that will be executed outside the group with the expanded value of the +% internal quotient. When |\x| is finished it does not exist any more as well as any +% value that was assigned or defined within the group. +% \begin{macrocode} +\def\dividi#1\per#2\in#3{% + \begingroup + \wt@Numer #1\relax \wt@Denom #2\relax + \ifdim\wt@Denom<\z@ \wt@Denom -\wt@Denom \wt@Numer -\wt@Numer\fi + \ifdim\wt@Numer<\z@ \def\wt@segno{-}\wt@Numer -\wt@Numer\fi + \ifdim\wt@Denom=\z@ + \edef\wt@Q{\ifdim\wt@Numer<\z@-\fi\strip@pt\maxdimen}% + \else + \wt@Num=\wt@Numer \wt@Den=\wt@Denom \divide\wt@Num\wt@Den + \edef\wt@Q{\number\wt@Num.}% + \advance\wt@Numer -\wt@Q\wt@Denom \wt@I=6 + \@whilenum \wt@I>\z@ \do{\wt@dividiDec\advance\wt@I\m@ne}% + \fi + \edef\x{\noexpand\endgroup\noexpand\def\noexpand#3{\wt@segno\wt@Q}} + \x +} +% \end{macrocode} +% +% The cycle for the long division consists in multiplying the remainder in +% |\wt@Numer| by ten, then reassigning the dimension value to the numerator +% integer counter so as to determine a new digit of the quotient in |\wt@q|. After +% this, this digit is appended by means of an expanded definition of the internal +% quotient, but it is used also for determining the new remainder in the +% |\wt@Numer| dimension register. Since the iteration is performed six times, six +% fractional digits are determined by this procedure, probably one digit too many, +% but its better one too many than the opposite. +% \begin{macrocode} +\def\wt@dividiDec{% + \wt@Numer=10\wt@Numer \wt@Num=\wt@Numer \divide\wt@Num\wt@Den + \edef\wt@q{\number\wt@Num}\edef\wt@Q{\wt@Q\wt@q}% + \advance\wt@Numer -\wt@q\wt@Denom} +% \end{macrocode} +% +% Now we define the dimension register that is to contain the desired table width. +% We further define the start of the tabular typesetting that will be useful in a while. +% Actually the table preamble is being saved into a macro, so that when the +% \meta{width} and the \meta{column descriptors} are given to the opening +% environment statement, these saved quantities can be used again and again. +% +% \begin{macrocode} +\newdimen\wt@width +\def\wt@starttabular{\expandafter\tabular\expandafter{\wt@preamble}} +% \end{macrocode} +% +% The environment opening as well as the environment closing are defined by +% means of low level commands. Due to the syntax of the opening command that +% requires two compulsory arguments, these are saved in the recently defined +% dimension register and to a macro respectively; anotehr macro |\wt@getTable| is +% used to get the body of the table; the |\end{widetable}| statement +% represents the ending delimiter of the table contents. +% +% \begin{macrocode} +\def\widetable#1#2{% + \def\@tempC{widetable}\setlength{\wt@width}{#1}% + \def\wt@preamble{#2}\wt@getTable} +% \end{macrocode} +% +% A new boolean, |wt@scartare|, is defined; this boolean variable will be set true in +% order to detect if the table body is is not well formed, with |\begin| and |\end| +% statements tha don't match, and the like; actually the |widetable| environment can +% contain other environmente, even another |widetable| environment, but the +% external one should not be upset by the internal ones. In order to achieve this +% result, it is necessary that any embedded environment is hidden int a group +% delimited by a pair of matching braces. +% \begin{macrocode} +\newif\ifwt@scartare\wt@scartarefalse +% \end{macrocode} +% +% The closing statement will acttually do the greatest part of the job. First of all if +% the above mentioned boolean variable is true, it skips everyting and it does not +% set any table; but if the boolean variable is false, the table body is well formed +% and it can do the job as described in the previous sections. It first sets +% |\tabcolsep| to zero and sets the resulting table in box zero; the lower +% level |tabular| with the information saved into |\wt@startabular| and the body of +% the table contained into the token register zero. +% +% Then it sets |\tabcolsep| to 1\,cm (arbitrarily chosen) and typesets again the table +% into box two. The width of box zero is $l_0$ and that of box two is $l_1$; these +% are the lengths needed by the equation that evaluates the final typesetting glue. +% The arbitrary constant of 1\,cm is $t_1$, and the specified width $l$ is the +% dimension saved into |\wt@width|. The subtractions are operated directly on the +% dimension registers |\wt@width| (the numerator) and on the auxiliary register +% |\@tempdimenb|; the |\dividi| command is executed in order to get the quotient +% in |\@tempA|, and the final definitive value of |\tabcolsep| is eventually computed. +% The table is finally typeset without using boxes, while the contents of box zero +% and two are restored upon exiting the environment to any value they might have +% contained before entering |widetable|. +% \begin{macrocode} +\def\endwidetable{% + \ifwt@scartare + \noindent\null + \else + \tabcolsep=\z@ + \setbox\z@=\hbox{\wt@starttabular\the\toks@\endtabular}% + \tabcolsep=1cm\relax + \setbox\tw@=\hbox{\wt@starttabular\the\toks@\endtabular}% + \advance\wt@width-\wd\z@ + \@tempdimb=\wd\tw@ + \advance\@tempdimb-\wd\z@ + \dividi\wt@width\per\@tempdimb\in\@tempA + \tabcolsep=\@tempA\tabcolsep + \wt@starttabular\the\toks@\endtabular + \fi + \ignorespacesafterend +} +% \end{macrocode} +% +% Of course other actions must be performed before executing the closing +% environment statement. We need a macro |wt@finetabella| that is equivalent to +% the ending environment statement. +% \begin{macrocode} +\def\wt@finetabella{\end{widetable}}% +% \end{macrocode} +% +% We finally can define the all important macro that gets the table body; it requires +% two delimited arguments: in |#1| the table body and, after the |\end| command, +% the closing environment name will be set in |#2|. The environment name is +% assigned to the macro |\@tempB|, which is checked against the correct name +% |widetable| saved in the macro |\@tempC| by the opening command. If the names +% match, then the table body is assigned to the token register zero, to be used later +% on by the typesetting macros. But if the names don't match, then something went +% wrong and a package message is issued to explain what happened and how the +% program will manage the situation. +% +% Specifically the names may not match if a cell contained another environment and +% its whole |\begin{...}...\end{...}| was not closed within a pair of matched +% braces. If an enclosed environment is hidden within a group, the delimited macro +% |\wt@getTable| will ignore such embedded environment, otherwise it will get a +% non matching name and messy things might happen. Besides warning about this +% fact, the body of the table, at least what has been read by the macro, will be +% discarded and substituted with a box containing a message; therefore a table will +% be typeset, but not the desired one. The remaining part of the body remains in +% the input stream and might cause, presumably, strange errors, such as |&| +% characters used outside a tabular or array environment. We must take care of this +% so that the typesetting procedure does not crash. +% \begin{macrocode} +\def\wt@getTable#1\end#2{\def\@tempB{#2}% + \ifx\@tempB\@tempC + \toks@={#1}% + \expandafter\wt@finetabella + \else + \PackageWarning{widetable}{% + The table contains environment `\@tempB' % + \MessageBreak + not enclosed in braces. This is expressly forbidden!% + \MessageBreak + The table is not typeset and is substituted% + \MessageBreak + with a framed box} + \noindent\framebox[\wt@width]{The table was not typeset because + it contains a visible \texttt{\char`\\end} in one or more cells.}\par + \expandafter\wt@finishTable + \fi +} +% \end{macrocode} +% +% In order to avoid a complete mess, we have to iteratively gobble the rest of the +% input stream until a valid |\end{widetable}| is encountered; Actually the following +% macro will do a nice job in general, but it is not infallible if the input stream is +% really composed in a very bad way. In facts it calls itself again and again, always +% gobbling it arguments, until a valid terminating environment name matches the +% name |widetable|. +% \begin{macrocode} +\def\wt@finishTable#1\end#2{% + \def\@tempB{#2}% + \ifx\@tempB\@tempC + \wt@scartaretrue\expandafter\wt@finetabella + \else + \expandafter\wt@finishTable + \fi +} +\endinput +% \end{macrocode} +% +% \Finale +% \endinput diff --git a/Master/texmf-dist/source/latex/widetable/widetable.ins b/Master/texmf-dist/source/latex/widetable/widetable.ins new file mode 100644 index 00000000000..5f7dddf542d --- /dev/null +++ b/Master/texmf-dist/source/latex/widetable/widetable.ins @@ -0,0 +1,67 @@ +%% +%% ---------------------------------------- +%% +%% This system is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +%% +%% IMPORTANT NOTICE: +%% +%% Copyright 2009 Claudio Beccari +%% All rights reserved. +%% +%% Permission is granted to distribute verbatim copies of this file +%% together with widetable.dtx. +%% +%% No other permissions to copy or distribute this file in any form +%% are granted and in particular no permission to modify its contents. +%% +%% --------------- start of docstrip commands ------------------ +%% +\def\batchfile{widetable.ins} +\input docstrip.tex +\preamble + +Copyright 2009 Claudio Beccari All rights reserved. + + This system is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +IMPORTANT NOTICE: + +You are not allowed to change this file. + +You are allowed to distribute this file under the condition that +it is distributed together with widetable.dtx. + +If you receive only some of these files from someone, complain! + +You are NOT ALLOWED to distribute this file alone. You are NOT +ALLOWED to take money for the distribution or use of either this +file or a changed version, except for a nominal charge for copying +etc. +\endpreamble +\def\batchfile{widetable.dst} % ignored in distribution +\input docstrip.tex % ignored in distribution + +\keepsilent + +\Msg{*** File widetable.sty is being generated ***} + +\generateFile{widetable.sty}{t}{\from{widetable.dtx}{package}} + +\ifToplevel{ +\Msg{***********************************************************} +\Msg{*} +\Msg{* Now move (if it is not already there) widetable.sty } +\Msg{* to a folder on the LaTeX search path} +\Msg{*} +\Msg{* Documentation is obtained by LaTeXing widetable.dtx.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{***********************************************************} +} + +\endinput |