From 37dfbf6e61d5d1c4ff4e9535b896a0d3a216943e Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 1 Jan 2018 22:05:20 +0000 Subject: spreadtab (1jan18) git-svn-id: svn://tug.org/texlive/trunk@46185 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/spreadtab/README | 44 +- .../doc/latex/spreadtab/spreadtab-en.pdf | Bin 0 -> 569446 bytes .../doc/latex/spreadtab/spreadtab-en.tex | 1594 +++++++++++++++++++ .../doc/latex/spreadtab/spreadtab-fr.pdf | Bin 0 -> 600605 bytes .../doc/latex/spreadtab/spreadtab-fr.tex | 1594 +++++++++++++++++++ .../doc/latex/spreadtab/spreadtab_doc_en.pdf | Bin 632424 -> 0 bytes .../doc/latex/spreadtab/spreadtab_doc_en.tex | 1602 -------------------- .../doc/latex/spreadtab/spreadtab_doc_fr.pdf | Bin 684587 -> 0 bytes .../doc/latex/spreadtab/spreadtab_doc_fr.tex | 1602 -------------------- .../texmf-dist/tex/latex/spreadtab/spreadtab.sty | 729 +++++---- 10 files changed, 3567 insertions(+), 3598 deletions(-) create mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.pdf create mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.tex create mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.pdf create mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.tex delete mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.pdf delete mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.tex delete mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.pdf delete mode 100644 Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.tex (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/spreadtab/README b/Master/texmf-dist/doc/latex/spreadtab/README index 956bf8c9ec8..6370b6be5f4 100644 --- a/Master/texmf-dist/doc/latex/spreadtab/README +++ b/Master/texmf-dist/doc/latex/spreadtab/README @@ -1,24 +1,34 @@ -_____________________ + L'extension + spreadtab - spreadtab package - v0.4c - 2014/11/06 -_____________________ + v0.4d -This package provides spreadsheet features for LaTeX table environments. + 1er janvier 2018 -It allows to construct tables in a manner similar to a spreadsheet. The cells -of a table have row and column indices and these can be used in formulas to -generate values in other cells. +Author : Christian Tellechea +Email : unbonpetit@netc.fr (CT) + Commentaires, signalements de bugs et + suggestions bienvenus +Licence : Released under the LaTeX Project Public License v1.3c or + later, see http://www.latex-project.org/lppl.txt -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +---------------------------------------------------------------------- + R\'esum\'é + +Cette extension met \`a disposition des fonctionnalit\'es de tableur +dans les environnements tableaux de LaTeX. -Ce package permet d'imiter le fonctionnement d'un tableur dans les -environnements tableau de LaTeX. +Les cellules d'un tableau ont des coordonn\'ees repr\'esentant leur +ligne et colonne, et par cet interm\'ediaire, peuvent \^etre +ins\'er\'ees dans des formules pour g\'en\'erer des valeurs dans +d'autres cellules. -Les cellules d'un tableau ont des coordonn\'ees repr\'esentant leur ligne et -colonne, et par cet interm\'ediaire, peuvent \^etre ins\'er\'ees dans des -formules pour g\'en\'erer des valeurs dans d'autres cellules. +---------------------------------------------------------------------- + Abstract + +This package provides spreadsheet features for LaTeX table +environments. - Christian Tellechea - \ No newline at end of file +The cells in a table have coordinates representing their row and +column, and by this way can be inserted into formulas to generate +values in other cells. \ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.pdf b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.pdf new file mode 100644 index 00000000000..065d8568330 Binary files /dev/null and b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.pdf differ diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.tex b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.tex new file mode 100644 index 00000000000..3037fba1366 --- /dev/null +++ b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-en.tex @@ -0,0 +1,1594 @@ +% Manual of the "spreadtab" package +\documentclass[english,a4paper,10pt]{article} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[a4paper,margin=2.6cm]{geometry} +\usepackage[table]{xcolor} +\usepackage{amsmath,amssymb,textcomp,array,arydshln,tabularx,listings,numprint,xspace,spreadtab,fancyhdr,libertine,babel,enumitem} +\usepackage[italic]{mathastext} +\usepackage[scaled=0.8]{luximono} +\fancyhead[L]{} +\fancyhead[C]{\small\bfseries\ST} +\fancyhead[R]{\scriptsize\slshape \leftmark} +\fancyfoot[l]{} +\fancyfoot[c]{} +\fancyfoot[r]{\thepage} +\usepackage[bottom]{footmisc} +\usepackage[protrusion=true,final,verbose=true,babel=true]{microtype} + +\makeatletter +\definecolor{ST@bckgcolor}{rgb}{0.87,0.9,1} +\definecolor{ST@codebckgcolor}{rgb}{0.9,0.9,0.9} +\definecolor{ST@keywordstc}{rgb}{0.7,0,0} +\definecolor{ST@keywordslatex}{rgb}{0,0,1} +\definecolor{ST@arguments}{rgb}{0,0,0} +\definecolor{ST@comments}{rgb}{0.5,0.5,0.5} +\lstset{% + language=[AlLaTeX]TeX,float=hbp,basicstyle=\footnotesize\ttfamily,identifierstyle=\color{ST@arguments},% + keywordstyle=\color{ST@keywordslatex},commentstyle=\itshape\color{ST@comments},% + columns=fixed,tabsize=4,frame=single,extendedchars=false,% + showspaces=false,showstringspaces=false,numbers=left,numberstyle=\tiny\ttfamily,% + breaklines=true,breakindent=3em,backgroundcolor=\color{ST@bckgcolor},breakautoindent=true,% + captionpos=t,xleftmargin=1em,xrightmargin=1em,lineskip=0pt,% + numbersep=1em,classoffset=1,% + morekeywords={% les macros et commandes de spreadtab + spreadtab,endspreadtab,SThiderow,SThidecol,STsavecell,STautoround,STmessage,STsetdecimalsep,STtransposecar,STdebug,STdisplaytab,STsetdisplaymarks,% + STnumericfieldmarker,STprintnum,STtextcell,STcopy,STtag,STmakegtag,STeol,fact,id,ifeq,ifgt,iflt,numtofrshortdate,% + numtoengshortdate,numtofrlongdate,numtoenglongdate,numtofrmonth,% + numtoengmonth,numtofrday,numtoengday,sum,rand,randint,sumprod,% + frshortdatetonum,engshortdatetonum,englongdatetonum,frlongdatetonum,gcd,lcm,tag,cell,row,col,value},% + keywordstyle=\color{ST@keywordstc},classoffset=0} + +%%%%%%%%%%% environnement OOcalc +\newcount\cntlin +\newcount\cntcol + +\newtoks\t@b +\long\def\ifremain@lines#1\\#2\@nil{% + \csname @\ifx\@empty#2\@empty second\else first\fi oftwo\endcsname} +\long\def\subst@eol#1\\#2\@nil{\addtot@b{#1\\\cline{1-1}\hdashline}% + \ifremain@lines#2\\\@nil{\addtot@b&\subst@eol#2\@nil}{\addtot@b{#2\end{tabular}}}} +\long\def\collect@body#1\end{\subst@eol#1\@nil\end} + +\newcommand\addtot@b[1]{\t@b\expandafter{\the\t@b#1}} +\newcommand\edftot@b[1]{\edef\temp@{#1}\expandafter\addtot@b\expandafter{\temp@}} + +\newenvironment{OOocalc}[2][1.5cm]{% #1=largeur colonnes #2 = nombre de colonnes + \newcolumntype w{>{\centering\arraybackslash}m{#1}}% + \arrayrulewidth0.4pt\dashlinedash0.4pt\relax\dashlinegap3pt + \global\cntlin\m@ne\global\cntcol\z@ + \tabfont + \tabcolsep0pt + \t@b{\begin{tabular}{% + |>{\cellcolor{tabheadcolor}% + \global\cntcol\z@\global\advance\cntlin\@ne + \centering\arraybackslash + \ifnum\cntlin>\z@\tableheadformat\number\cntlin\fi} + m{2em}|*{#2}{w:}}% + \hline + \rowcolor{tabheadcolor}}% + \loop + \ifnum\cntcol<#2 + \advance\cntcol\@ne + \addtot@b{&\multicolumn{1}{>\centering m{#1}|}}% + \edftot@b{{\noexpand\tableheadformat\@Alph\cntcol}}% + \repeat + \addtot@b{\\\hline&}% + \collect@body}{\the\t@b} + +\def\engdate{\expandafter\engdatei\STdate\@nil} +\def\engdatei#1/#2/#3\@nil{\number#3\relax\space\ifcase #2 \or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi{} #1} +\makeatother + +% commandes de personnalisation de OOcalc +\newcommand*\tabfont{\fontfamily{phv}\selectfont\footnotesize}% police du tableau (helvetica ici) +\newcommand*\tableheadformat{\bfseries}% police des en-têtes du tableau (en gras) +\colorlet{tabheadcolor}{gray!40}% couleur de font des en-têtes du tableau +\colorlet{palepink}{pink!80} +\colorlet{lightpink}{pink!30} +\colorlet{palegreen}{green!60} +\colorlet{lightgreen}{green!30} +\newcommand\CC[1]{\cellcolor{#1}} + +\newcommand\verbinline[1][]{\lstinline[breaklines=false,basicstyle=\normalsize\ttfamily,#1]} +\newcommand\ST{\textsf{\STname}\xspace} +\newcommand\falseverb[1]{\texttt{\detokenize{#1}}} + +\usepackage[bookmarks=true,bookmarksopen=true,colorlinks=true,hyperfootnotes=false,filecolor=black,linkcolor=blue,urlcolor=magenta,pdfauthor={Christian TELLECHEA},pdftitle={spreadtab},pdfsubject={Spreadtab provides spreadsheet features for LaTeX table environments},pdfkeywords={spreadtab},pdfcreator={LaTeX}]{hyperref} + +\begin{document} +\parindent0pt\pagestyle{fancy} +\begin{titlepage} + \null\par\vfill + \begin{center} + \begin{minipage}{0.75\linewidth} + \begin{center} + \Huge\bfseries \ST\par\vspace{5pt} + \small v\STver\par\vspace{25pt} + \normalsize User's manual + \end{center} + \end{minipage} + \end{center} + \vspace{1cm} + \begin{center} + Christian {\sc Tellechea}\par\small + \href{mailto:unbonpetit@netc.fr}{\texttt{\textbf{unbonpetit@netc.fr}}}\par\vspace{5pt} + \engdate + \end{center} + \vfill + \begin{center} + \begin{minipage}{0.8\linewidth} + \noindent\hrulefill\par + \hfill\textbf{\textit{Abstract}}\hfill{}\medskip\par\footnotesize + This package provides spreadsheet features for \LaTeX{} table environments.\par\medskip + The main feature allows the user to construct tables in a manner similar to a spreadsheet where cells are used in formulas to generate values in other cells. The package computes the formulas in the correct order and finally displays the table with the numeric results.\par + \hrulefill + \end{minipage} + \end{center} +\vfill{} +\end{titlepage} + +\tableofcontents\newpage +\parskip\medskipamount +\section{Introduction} + +\subsection{Presentation} +This package allows us to construct tables in a manner similar to a spreadsheet. The cells of a table have row and column indices and these can be used in formulas to generate values in other cells. + +The package requires $\varepsilon$-\TeX, \LaTeXe{} and the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} package, which performs arithmetic on cell values. Also, the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/xstring/}{\texttt{\textbf{xstring}}} package is needed in its \falseverb{v1.5d [2010/03/28]} version or later.\medskip + +The package is compatible with \emph{all} tabular environments, and assumes that `\verb=&=' is used to delimit columns and `\verb-\\-' to end lines (but see page~\pageref{STeol}). This compatibility requirement led me to program \ST so that it works independently of the table environment. Thus, reading the table, processing and calculating the formulas is done \emph{before} the environment table `sees' the body of the table.\medskip + +Consequently, \ST proceeds in 3 main stages before \verbinline=\begin{}= sees the table: +\begin{itemize} + \item first, it reads the body of the table, divides it in lines and cells, and in each cell, seeks a possible formula; + \item then, it computes the formulas in the cells, taking care for each to previously calculate all the dependent cells. The calculations are done by the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} package; + \item finally, it is necessary to rebuild the table, replacing each formula by its numerical calculated value and handing over to the environment name specified by the user. +\end{itemize} +The syntax in both the following is allowed (and equivalent), where \verb-- is the name of any table environment available with \LaTeX{} or with a package:\par\nobreak +\begin{minipage}{0.48\linewidth} +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\begin{spreadtab}{{}{}} + table with formulas and numbers +\end{spreadtab} +\end{lstlisting} +\end{minipage}\hfill or\hfill +\begin{minipage}{0.48\linewidth} +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\spreadtab{{}{}} + table with formulas and numbers +\endspreadtab +\end{lstlisting} +\end{minipage} + +After the work of \ST, we get a display as if we had written: +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\begin{}{} + table with numbers +\end{} +\end{lstlisting} + +Although having features resembling those of a spreadsheet with \LaTeX{} is appreciable, the 3 stages described above take time, and above all, \verb-fp- is slow in its calculations. The \ST environment leads to \emph{much slower compilation} than with a classical table. + +Moreover, \ST \emph{cannot stand in for a spreadsheet program}. Indeed, it has very few features, and it does not provide visual assistance. This point may cause difficulty\footnote{I certify that, with use, this discomfort tends to disappear (if you do not work with huge tables, of course).} for big or complex tables. The syntax of \ST is also another difficulty. However, the advantage of this package is that it makes it possible to write \emph{in the \LaTeX{} code} tables involving calculation when these tables are usually exported\footnote{I mention the two main exportation programs: \href{http://calc2latex.sourceforge.net/}{\texttt{\textbf{cacl2latex}}} for `calc' (Open Office), and \href{http://www.ctan.org/tex-archive/support/excel2latex/}{\texttt{\textbf{excel2latex}}} for `excel' (Microsoft Office).} from a spreadsheet program to \LaTeX{} code. Consequently, it becomes possible to avoid the disadvantages of the exportation programs: fine tuning often necessary to obtain exactly what you want, exported tables containing the values only (formulas are lost when exportation is done), no compatibility with all types of environments, exportation must be started again if a single number or formula is modified in the table. + +\subsection{Motivation} +A few months before I started to write this package, Derek \textsc{O'Connor} had pointed out that nothing was available in the world of \LaTeX{} packages to imitate --~even a little~-- the behaviour of spreadsheet programs. I found the challenge interesting and I started writing this package as a good programming exercise. + +The road was long before reaching this version and I especially want to thank Christophe \textsc{Casseau} for his early interest and for the suggestions he made, and more recently Derek \textsc{O'Connor} for his advice and for the constructive discussions we have had. I also thank Andrew \textsc{Parsloe} for proofreading the english translation of this manual. + +\section{Basic features} +A table is a rectangular array of cells which may be viewed as a set of cells arranged in horizontal rows or vertical columns. + +\label{STeol}By default, \ST expects a `\verb-\\-' at the end of lines, which is usual in tables. This end of line marker can be changed via the \verbinline-\STeol{}- command. We can write for example \verbinline-\STeol{\tabularnewline}-. It is important to remember that the ends of lines to be inserted in the final table will always be `\verb-\\-' even if the end of line marker that \ST sees when it \emph{reads} the table is different. + +\subsection{Absolute references} +A table cell is identified by the pair \falseverb{}\footnote{Note: this is the opposite to the standard matrix convention}, where: +\begin{itemize} + \item \verb|| is a letter from \falseverb a to \falseverb z, and \falseverb a is the first column on the left: it is limited to 26 columns, which should be sufficient for the majority of cases; the letter can be upper or lowercase; + \item \verb|| is a positive integer representing row number. The row number 1 is the top row. +\end{itemize} +Here are examples of absolutes references: \falseverb{b4} or \falseverb{C1} or \falseverb{d13}. Locations of cells appear clearly in the spreadsheet-like table below: +\begin{center} +\begin{OOocalc}[6em]{5} +&&&&\\&&&&\\&&&&\\&&&&\\&&&&\\ +\end{OOocalc} +\end{center} +This example calculates the sum of each row and each column and then calculates the grand total:\par\nobreak +\begin{minipage}{0.75\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{rr|r}} +22 & 54 & a1+b1 \\ +43 & 65 & a2+b2 \\ +49 & 37 & a3+b3 \\ +\hline +a1+a2+a3 & b1+b2+b3 & a4+b4 +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.25\linewidth} +\centering +\begin{spreadtab}{{tabular}{rr|r}} +22 & 54 & a1+b1 \\ +43 & 65 & a2+b2 \\ +49 & 37 & a3+b3 \\ +\hline +a1+a2+a3 & b1+b2+b3 & a4+b4 +\end{spreadtab} +\end{minipage}% + +For people familiar with maths, this other example calculates the first lines of Pascal's triangle:\par\nobreak +\begin{minipage}{0.75\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{ccccc}} +1 & & & & \\ +a1 & a1 & & & \\ +a2 & a2+b2 & b2 & & \\ +a3 & a3+b3 & b3+c3 & c3 & \\ +a2 & a4+b4 & b4+c4 & c4+d4 & d4 +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.25\linewidth} +\centering +\begin{spreadtab}{{tabular}{ccccc}} +1 & & & & \\ +a1 & a1 & & & \\ +a2 & a2+b2 & b2 & & \\ +a3 & a3+b3 & b3+c3 & c3 & \\ +a2 & a4+b4 & b4+c4 & c4+d4 & d4 +\end{spreadtab} +\end{minipage}% + +\subsection{Relative references} +To refer to a cell, it may be convenient to specify its position relative to where the formula is written. Thus, the relative coordinates of a cell are 2 relative numbers written using this syntax: \falseverb{[x,y]} where \falseverb x is the horizontal offset from the cell containing the formula and \falseverb y is the vertical offset. For example, \falseverb{[-2,3]} refers to the cell located 2 columns before (on the left) and 3 rows after (below) the cell where the formula is located. + +Here is the same table as above but the references are relatives and the \verbinline-matrix- environment of the \href{http://www.ctan.org/tex-archive/macros/latex/required/amslatex/math/}{\texttt{\textbf{amsmath}}} package is used:\par\nobreak +\begin{minipage}{0.82\linewidth} +\begin{lstlisting} +$ +\begin{spreadtab}{{matrix}{}} +1\\ +[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] +\end{spreadtab} +$ +\end{lstlisting} +\end{minipage}\hfill +\begin{minipage}{0.15\linewidth} +\centering +$ +\begin{spreadtab}{{matrix}{}} +1\\ +[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] +\end{spreadtab} +$ +\end{minipage}% + +We note that relative references are more appropriate here, since only 2 different references are used: \falseverb{[0,-1]} which refers to the cell above and \falseverb{[-1,-1]} which refers to the cell located to the NW of the current cell.\medskip + +Absolute and relative references can be mixed in a formula. + +\subsection{Text cells} +If you want to put only text in a cell, you must tell \ST that the cell should not be calculated. Simply place somewhere in the cell the character `\falseverb @' with its usual catcode 12. The cell will be ignored by \ST which will consider it as an inert cell impossible to reference\footnote{There is an exception, see page \pageref{datetonum}.} elsewhere in the table. + +Example:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ values of $x$ & -5 & -1 & 4 \\ +@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ values of $x$ & -5 & -1 & 4 \\ +@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline +\end{spreadtab} +\end{center} +The control sequence \verbinline=\STtextcell= expands to the character `\falseverb @'. It is possible to redefine it; for example, after \verbinline-\renewcommand\STtextcell{`}-, a cell containing the char \verb=`= will be understood as a text cell. + +Moreover, if a cell is empty or filled with spaces, \ST will consider it as a text cell. + +\subsection{Mixed cells} +In reality, each cell is composed of two fields. The first is a \emph{numeric field} containing the formula; the second is a \emph{text field}, ignored by \falseverb{fp} and not taken into account for calculations: +\begin{itemize} + \item if nothing is specified in a cell, the entire cell is the number field, and the text field is empty (this was the case for all table cells of Pascal's triangle seen above); + \item if the cell contains the `\falseverb @' character, then the entire cell is the text field. The numeric field is empty and inaccessible; + \item if the cell contains the marker `\verb-:=-', then the following argument between braces is the numeric field, and everthing else is the text field. The cell has this structure:\par + \hfil\verb-:={numeric field}-\hfil\null\par + The marker `\verb-:=-' is the expansion of the control sequence \verbinline-\STnumericfieldmarker-. It is possible to redefine it, for example:\par\smallskip + {\centering\verbinline-\renewcommand\STnumericfieldmarker{\=}-\par\smallskip} + In this case, the expansion of the marker `\verb-\=-' would have no importance and would not be involved in the process. For \ST, it is only a token showing where the formula begins. This token is sought and recognized but is never expanded. +\end{itemize} +Once the \falseverb{numeric field} is computed, `\falseverb{:={numeric field}}' is replaced by the numeric value. + +Note that `\verb-:={numeric field}-' may be inside brackets, whatever be the level of nesting. For example, if a cell contains \verb-\textbf{:={a1+1}}- and if the numeric value of the cell \falseverb{a1} is 5, then finally, the cell will contain \verb-\textbf{6}-\medskip + +Here is a simple example:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +value 1 : :={50} & value 2 : :={29} & average : \textbf{:={(a1+b1)/2}}\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +value 1 : :={50} & value 2 : :={29} & average : \textbf{:={(a1+b1)/2}}\\\hline +\end{spreadtab} +\end{center} +If `\verb-:=-' is written in a cell with an empty argument like this `\verb-:={}-', then the cell is understood as a text cell. In fact, `\verb-:={}-' behaves like `\verb-@-', but they are \emph{not} equivalent: `\verb-:={}-' allows the cell to receive a formula from another with \verbinline-\STcopy- (see next section) while it is impossible with `\verb-@-'. + +\subsection{Copy a formula} +To avoid having to copy formulas into adjacent cells, the \ST package provides the \verbinline-\STcopy- command. + +This command must be written in a cell with this syntax: +\begin{center} +\verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formula}- +\end{center} +where $x$ and $y$ are positive numbers that represent horizontal and vertical offsets relative to the cell where the command is. With the cell containing the command (the source cell), these offsets define a range of cells which will receive the \verb--\footnote{The copy can only be done to cells located on the right and below the cell containing the macro.}. The command \verbinline-\STcopy- must \emph{not} be in a cell where there is a numeric field marker `\verb-:=-'. + +Here is how the copy is made: it starts from the cell where the command \verbinline-\STcopy- is. For the other cells, all the coordinates in the formula are modified taking into account the offsets from the source cell. For example, if the source cell contains the formula \verb-a1+b2+c3-, and the target cell is located 2 columns rightwards and 5 rows below then, this formula becomes: \verb-c6+d7+e8-. The formula can also contain relative references but, since they are relative, they are not modified. + +Preceded by `\verb-!-', a coordinate in a formula is not modified when the formula is copied. For example, if the source cell contains \verb-a!1+!b2+!c!3- and the target cell is located 2 columns rightwards and 5 rows below then, this formula becomes: \verb-c1+b7+c3-. The feature is compatible with relative coordinates. Let's suppose a cell contains this formula: \verb|[-1,!-1]+[!-1,1]+[!1,!2]|. As usual, let's say that this formula is copied to the cell located 2 columns rightwards and 5 rows below: this formula becomes: \verb|[-1,-6]+[-3,1]+[-1,-3]|. + +The `\verb-!-' character is the expansion of the control sequence \verbinline-\STtransposecar-. It may be changed to any other with \verbinline-\renewcommand\STtransposecar-\verb-{}-. The `\verb-!-' character, used by default, keeps its 13 catcode and remains active if the \verb-babel- package is loaded with the \verb-frenchb- option. + +In `\verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formula}-', if $x$ is omitted, the copy is made to the cells rightwards, up to the right edge of the table. With $y$, it is the same: if this number is omitted, the copy is done to the cells below until the bottom of the table is reached. If $x$ or $y$ is equal to 0, the copy is limited to the column or row of the source cell. Instead of writing \verb-v0- or \verb->0-, it is possible to write \verb-v- or \verb->-. + +Here are some examples: +\begin{tabular}{cl}\hline +\verb-{>3,v1}- & copy to 3 columns rightwards and 1 row below\\ +\verb-{>3}- & copy to 3 cells on the right\\ +\verb-{v1}- & copy to the cell below\\ +\verb-{>}- & copy rightwards up to the right edge\\ +\verb-{v}- & copy below\\ +\verb-{v,>}- & copy to the right and below until the end of the table\\\hline +\end{tabular} + +It is easy to generate the multiplication table from 1 to 10: + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} +\hline +@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline +1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ +\STcopy{v}{a2+1} & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} +\hline +@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline +1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ +\STcopy{v}{a2+1} & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\\hline +\end{spreadtab} +\end{center} + +If the numeric field of a target cell is not empty, it is not replaced and the copy is not done for this cell. + +If 2 or more \verbinline-\STcopy- commands in several source cells have the same target cell, then, the formula this latter receives is the one contained in the last \verbinline-\STcopy- command when the table is read from top left to bottom right. In the spreadsheet-like example below, the \verbinline-\STcopy- in the pink cell \falseverb{B1} has its target range partially covered by the one of the green cell \falseverb{C3}. +\begin{center} +\begin{OOocalc}[2.3cm]{6} +1 &\CC{palepink}\ttfamily\textbackslash STcopy \{v,>\}\{!a1+1\} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} \\ +2 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} ~\par~ \\ +3 &\CC{lightpink} &\CC{palegreen}\ttfamily\textbackslash STcopy \{>2,v1\}\{!a3*10\}&\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink} \\ +4 &\CC{lightpink} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink}~\par~ \\ +5 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink}~\par~ \\ +\end{OOocalc} +\end{center} +Here is this example, treated by \ST below. In this table, the cell \verb-b5- (numeric field alone) and the cell \verb-c5- (text field + numeric field) stay unchanged since their numeric fields are not empty: +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 &\STcopy{v,>}{!a1+1} & & & & \\\hline +2 & & & & & \\\hline +3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline +4 & & & & & \\\hline +5 & -1 & a:={0}b & & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 &\STcopy{v,>}{!a1+1} & & & & \\\hline +2 & & & & & \\\hline +3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline +4 & & & & & \\\hline +5 & -1 & a:={0}b & & & \\\hline +\end{spreadtab} +\end{center} +As mentioned in the last chapter, you can also copy a formula to a text cell containing an empty numeric field (that is to say a cell containing `\verb-:={}-'). In this case, the formula is copied inside the brackets. On the other hand, a cell containing text `\verb-@-' cannot receive a formula when copying and the cell remains purely textual. + +Example : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 & 2 & 3 & 4 & 5 & 6 \\\hline +X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 & 2 & 3 & 4 & 5 & 6 \\\hline +X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline +\end{spreadtab} +\end{center} + +\section{Features for formatting the table} +\subsection{Decimal seprarator} +The \verb-fp- package returns its results with the decimal point separator. After the job of \verb-fp-, \ST can change this decimal separator: everything happens as if the results returned by \verb-fp- were taking this into account. The command \verbinline-\STsetdecimalsep- takes a mandatory argument which is the character used as decimal separator: +\begin{center} +\verbinline-\STsetdecimalsep-\verb-{}- +\end{center} +For example, French users should write this in the preamble of the document: +\begin{center} +\verbinline-\STsetdecimalsep{,}- +\end{center} +For numeric fields located in math mode, the comma is considered as a math punctuation, which explains why it is followed by a space. To pevent this behaviour, it can be written inside brackets: + +\begin{minipage}{0.65\linewidth} +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +3,14 is not displayed like $3,14$.\par +3,14 is displayed like $3{,}14$ +\end{lstlisting} +\end{minipage}\hfill +\begin{minipage}{0.35\linewidth} +3,14 is not displayed like $3,14$.\par +3,14 is displayed like $3{,}14$ +\end{minipage}% + +When cells are in math mode, you can\footnote{It is preferable to use the \texttt{numprint} package to format the results. You can also change the math code of the comma: \texttt{\textbackslash mathcode`,="013B\textbackslash relax}. This trick puts the comma in the class 0 of the ordinary signs while its natural class is 6 (punctuation signs).} use this feature and ask \ST to replace the decimal point by a comma inside braces with the command \verbinline-\STsetdecimalsep{{,}}-. In these tables where each cell is in math mode, the space after the commas are neutralized in the second table: + +\begin{minipage}{0.65\linewidth} +\begin{lstlisting} +\STsetdecimalsep{,} +\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline +@x & @y & @\text{Average}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab}\par\smallskip +\STsetdecimalsep{{,}} +\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline +@x & @y & @\text{Average}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.35\linewidth} +\centering +\STsetdecimalsep{,} +\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline +@x & @y & @\text{Average}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab}\par\smallskip +\STsetdecimalsep{{,}} +\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline +@x & @y & @\text{Average}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab} +\end{minipage} + +\subsection{Number formatting and the {\ttfamily fp} package} +All calculations are made by the \verb-\FPeval- macro\footnote{This macro accepts infix or postfix notation. Consequently, both can be used to write formulas in a cell. For example the infix formula `\falseverb{a1+b1}' is equivalent to the postfix ones `\falseverb{a1 b1 add}' or `\falseverb{a1 b1 +}'.} of the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} package. This package provides all necessary arithmetical functions along with various scientific and trigonometric functions. Calculations are made with 18 decimal digits of precision, and \falseverb{fp} displays \emph{all} the decimals! + +The number of digits displayed can be controlled in various ways: +\begin{itemize} + \item the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/numprint/}{\texttt{\textbf{numprint}}} package can be used in order to properly display numbers; + \item \verb=fp= can round or truncate numbers with \verb-round(number,integer)- or \verb-trunc(number,integer)- but the syntax makes this tedious to write if this is needed for many cells; + \item \ST can round \emph{all} the numbers in the table with the macro \verbinline-\STautoround- whose argument is number of digits in the decimal part. If the argument is empty, no rounding is done. If the starred macro \verbinline-\STautoround*- is used, the decimal part is filled with 0 as necessary. +\end{itemize} +In this example, floating point numbers are rounded to 6 digits:\par\nobreak +\begin{lstlisting} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab}\medskip + +\STautoround*{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab}\medskip + +\STautoround*{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab} +\end{center} + +All the numbers contained in the final table, either typed as is or coming from a calculation are processed by the macro\verbinline-\STprintnum-. By default, this macro has no effect on its argument and is defined this way: +\begin{center} + \verbinline-\newcommand\STprintnum[1]{#1}- +\end{center} +It is possible to round all the numbers via the \verbinline-\numprint- command from the \verb-numprint- package. To achieve this, the \verbinline-\STprintnum- command must be redefined:\par\nobreak +\begin{lstlisting} +\renewcommand\STprintnum[1]{\numprint{#1}} +\nprounddigits{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\renewcommand\STprintnum[1]{\numprint{#1}} +\nprounddigits{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{center} + +Here is another similar example where we test if the number to display is negative with the command \verbinline-\FPifneg- from the \verb-fp- package. If this happens, the number is displayed in red. The command \verbinline-\STautoround- was preferred to \verbinline-\nprounddigits- from the \verb-numprint- package because the latter adds unnecessary 0's. +\begin{lstlisting} +\STsetdecimalsep{.} +\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} +\STautoround{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STsetdecimalsep{.} +\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} +\STautoround{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{center} + +\subsection{End of lines and horizontal rules} +\ST recognizes the usual line breaks and horizontal rules \verb|\\| and \verb|\hline|. It is also possible to specify the optional argument in line break: \verb-\\[]-. + +For horizontal rules, it is possible to use:\par\nobreak +\begin{itemize} + \item \verb-\hline-; + \item \verb=\cline{x-y}= where \falseverb x and \falseverb y define the start and the end of the rule; + \item \verb=\hhline{}= where \verb== is the type of rule (read the manual of the \href{http://www.ctan.org/tex-archive/macros/latex/required/tools/}{\texttt{\textbf{hhline}}} package). + \item any command of the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/booktabs/}{\texttt{\textbf{booktabs}}} package: \verb-\toprule-, \verb-\midrule-, \verb-\bottomrule-, \verb-\cmidrule-, \verb-\addlinespace-, \verb-\morecmidrule- and \verb-\specialrule-. All the arguments of these macros, optional or mandatory are taken into account; + \item \verbinline-\noalign- and its mandatory argument can be written after \verb-\\-. +\end{itemize} +Example: +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*5c}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline +[0,1] & [-1,1] & & & \\ \cline{2-4} +1 & & & & \\ \hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{*5c}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline +[0,1] & [-1,1] & & & \\ \cline{2-4} +1 & & & & \\ \hline +\end{spreadtab} +\end{center} + +\subsection{Hide a row or column} +Sometimes, a column or a row is intended for intermediate calculations and does not need to be displayed in the final table. For this, \ST provides two control sequences \verbinline=\SThiderow= and \verbinline=\SThidecol= which, when placed in a cell, hide the row or column that contains the cell. + +An example:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ values of $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline +@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ +@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ +@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ values of $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline +@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ +@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ +@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline +\end{spreadtab} +\end{center} +The row containing $g(x)$ and column corresponding to the value 0 are hidden. + +Remember that the hidden rows and columns are \emph{invisible} to the tabular environment chosen by the user. Thus, only 4 columns have been defined (\falseverb{|r|ccc|}) and not 5 as seen by \ST. + +Just to see the difference, here is the table obtained when setting 5 columns in the preamble and not hiding any row or column:\par\nobreak +\begin{center} +\begin{spreadtab}{{tabular}{|r|cccc|}} +\hline +@ values of $x$ & -1 & 0 & 2 & 3 \\\hline +@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ +@$g(x)=x-10$ & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ +@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline +\end{spreadtab} +\end{center} + +\subsection{Save the result of a cell} +It may be necessary to save the numerical value of a cell to display it outside a formula or even outside the table. Here is how to do it: +\begin{center} +\verbinline-\STsavecell{}{}- +\end{center} +With a \verbinline-\global\def-\footnote{The \texttt{\string\def} command does not check if the macro it defines already exists.}, this command globally saves in \falseverb{} the result of the formula contained in the cell \falseverb{}.\medskip + +Only absolute references can be used since this command must be placed in the optional argument of the \verbinline-spreadtab- environment. + +Example:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} +\hline +10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline +\end{spreadtab} +\par\medskip +Here is the cell c1 : \result +\end{lstlisting} +\begin{center} +\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} +\hline +10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline +\end{spreadtab} +\par\medskip +Here is the cell c1 : \result +\end{center} +In order to save several cells, the command \verbinline-\STsavecell- can be put several times in the optionnal argument. + +Example:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline +@Speed (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ +@distance (km) & & & & 180\\\hline +@Time (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline +\end{spreadtab}\par\medskip +It lasts more than \hhh\ hours. +\end{lstlisting} +\begin{center} +\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline +@Speed (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ +@distance (km) & & & & 180\\\hline +@Time (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline +\end{spreadtab}\par\medskip +It lasts more than \hhh\ hours. +\end{center} + +\subsection{Display the value of a cell} +In order to display the numeric field of a cell in a textual field, we have seen that we could save this value in a control sequence and use this control sequence anywhere in the table. The process is somewhat tedious\ldots{} Indeed, \verbinline-\STsavecell- is not intended to be used in such a way. Its aim is to save the value of a numeric field for further use \emph{outside} the table. + +There is a simpler way to display the numeric field of a cell in a textual field using the syntax \verb-<>- which is replaced by the numeric field of the cell \verb-reference-, where the \verb-reference- can be absolute or relative. If the text between \verb-<<- and \verb->>- is not a reference, then \verb-<>- is left as is. The \verb-reference- must not contain any space; for example, if you write \verb-<< a1>>-, \ST does not uderstand it as a reference because of the space before `\verb-a1-'. + +Example in a textual cell \verb-a3-: +\begin{lstlisting} +\begin{spreadtab}{{tabular}{lr}} +@Sell price & 250 \\ +@Purchase price & 216 \\\hline +@Profit (<>-<>) & b1-b2 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{lr}} +@Sell price & 250 \\ +@Purchase price & 216 \\\hline +@Profit (<>-<>) & b1-b2 +\end{spreadtab} +\end{center} +Example in the mixed cell \verb-c1-: +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +23 & 32 & Average $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +23 & 32 & Average $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline +\end{spreadtab} +\end{center} +The characters used to delimit the reference are set to `\verb-<<-' and `\verb->>-' by default. They can be modified with the \verbinline-\STsetdisplaymarks- command whose arguments contain the left and right delimiters. For example, if you write \verbinline-\STsetdisplaymarks{|}{|}-, you will write \verb-|reference|- in order to display the content of the numeric field of the cell \verb-reference-. + +\subsection{The use of \ttfamily\textbackslash multicolumn} +\ST is compatible with the syntax \verbinline=\multicolumn{}{}{}= which merges \falseverb{} cells in a unique cell whose type and content are specified in the arguments. + +Even when using \verbinline=\multicolumn=, \ST maintains some consistency in the references. In this table where \verbinline-\multicolumn- is used, the absolute references are displayed:\par\nobreak +\begin{center} +\ttfamily +\begin{tabular}{|*7{c|}}\hline +a1&b1&c1&d1&e1&f1&g1\\\hline +a2&\multicolumn{2}{l|}{b2}&d2&e2&f2&g2\\\hline +\multicolumn{3}{|l|}{a3}&d3&\multicolumn{2}{l|}{e3}&g3\\\hline +\end{tabular} +\end{center} +Thus, whatever the number of merged cells, the next cell has a column number that takes into account the number of merged cells.\medskip + +In the last line, cells \falseverb{a3}, \falseverb{b3} and \falseverb{c3} are merged and consequently, the cells \falseverb{b3} and \falseverb{c3} \emph{do not exist} for \ST: it is not possible to refer to \falseverb{b3} or \falseverb{c3} anywhere in the table.\medskip + +In this example, every number in the top line is the product of the 2 numbers below:\par\nobreak +\begin{lstlisting} +\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} +\begin{spreadtab}{{tabular}{*6{K{0.5}}}} +\cline{2-5} +&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline +\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} +\begin{spreadtab}{{tabular}{*6{K{0.5}}}} +\cline{2-5} +&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline +\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline +\end{spreadtab} +\end{center} +The marker `\falseverb{:=}' is necessary in every cell where the command \verbinline-\multicolumn- is written. Without it, \ST would consider that the whole cell (i.e. \verb-\multicolumn{2}{|c|}{}-) as the formula, which is impossible to calculate. + +\section{Macro-functions} +The \falseverb{fp} package provides a limited set of operations and functions. If these are not sufficient then \ST allows the advanced programmer to write macros using the operations and functions of \falseverb{fp}. This section presents the macro-functions currently available\footnote{Many others should be written soon and be available in future versions of the package.}. There will be more details on how to program macro functions in the next version of this manual. + +\subsection{Mathematical macro-functions} +\subsubsection{Sum cells} +The macro-function \verbinline=sum= sums one or several ranges of cells. + +It should be used like this: \verbinline=sum(;;...;)=, where a range of cells is: +\begin{itemize} + \item either a single cell like \falseverb{a1} or \falseverb{[2,1]}; + \item or a rectangular area bounded by the upper-left cell and lower-right with this syntax:\par{\centering\verb=:=\par} + Here are some examples of such areas: \falseverb{a2:d5}, \falseverb{[-1,-1]:[2,3]}, \falseverb{b4:[5,1]}. +\end{itemize} +In cell ranges, if a cell does not have a numeric field (empty cell or text cell or merged cell with \verbinline-\mutlicolumn-), it is seen as 0 by \verbinline-sum-. + +In the following table, the sum of the binomial coefficients of Pascal's triangle is calculated:\par\nobreak +\begin{minipage}{0.75\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*5c}} +\multicolumn{5}{c}{sum: :={sum(a2:e6)}}\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1] & & & \\ +1 & & & & +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.25\linewidth} +\centering +\begin{spreadtab}{{tabular}{*5c}} +\multicolumn{5}{c}{sum: :={sum(a2:e6)}}\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1] & & & \\ +1 & & & & +\end{spreadtab} +\end{minipage}% + +\subsubsection{The \texttt{fact} macro} +The macro-function \verbinline=fact()= computes the factorial of its argument, assuming it is an \emph{integer} between 0 and 18 to avoid overflows\footnote{Indeed, for \falseverb{fp} the greatest integer is $10^{18}-1$. The factorial of 19 is greater than this.}. The \falseverb{} can also be a reference to a cell whose numeric field contains an integer.\medskip + +Here are the factorials from 0 to 8:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*9c}} + 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline +fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{*9c}} + 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline +fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) +\end{spreadtab} +\end{center} + +\subsubsection{The \texttt{sumprod} macro} +The function \verbinline=sumprod= multiplies the corresponding elements of 2 or more rectangular ranges and then adds these products. + +It should be used like this: \verbinline{sumprod(;;...;)}. All the ranges must have the same dimensions. + +In this simple example, the average age of a group of children aged from 10 to 15 years old is calculated:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{r*6c}} +@\Ages & 10 & 11 & 12 & 13 & 14 & 15\\ +@Number & 5 & 8 & 20 & 55 & 9 & 3\\\hline +@Average&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{r*6c}} +@Ages & 10 & 11 & 12 & 13 & 14 & 15\\ +@Number & 5 & 8 & 20 & 55 & 9 & 3\\\hline +@Average&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} +\end{spreadtab} +\end{center} +If any cell in the ranges is empty, pure text or merged with \verbinline-\multicolumn-, its numeric field is replaced by 0. + +\subsubsection{Random numbers} +The macro-functions \verbinline-randint- and \verbinline-rand- each returns a random number depending on its argument. + +It should be noted that the seed initializing the random sequence depends on the date and the minute at which the compilation is done. Thus, the random sequence of numbers given by this function will change between two compilations made at different times. If random numbers need to be repeatable, the private macro \verb-\ST@seed- must be cancelled and a seed should be chosen for \falseverb{fp}. Here is the code to do this:\par\nobreak +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\makeatletter +\renewcommand\ST@seed{}% redefines the private macro +\makeatother +\FPseed=27% gives a seed (any integer) to fp. +\end{lstlisting} +The macro-function \verbinline-randint([,])- returns a random \emph{integer} depending on its arguments: \verb== is an optional integer with default value 0. The random integer returned is in the interval \verb=[;=\linebreak[2]\verb=]=. + +The macro-function \verbinline-rand()- returns a random number between 0 and 1.\par\nobreak +\begin{lstlisting} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|cccc|}}\hline +@numbers in [0;1] &rand() &rand() &rand() &rand() \\ +@numbers in [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ +@numbers in [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ +\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|cccc|}}\hline +@numbers in [0;1] &rand() &rand() &rand() &rand() \\ +@numbers in [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ +@numbers in [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ +\hline +\end{spreadtab} +\end{center} + +\subsubsection{GCD and LCM} +The macro functions `gcd' and `lcm' compute the Greatest Common Divisor and the Least Common Multiple of the list of numbers in their argument: +\begin{center} +\verbinline-gcd(number1,number2,...,numberN)-\par +\verbinline-lcm(number1,number2,...,numberN)- +\end{center} +Example : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline +\multicolumn3{|c||}{@Numbers}& @GCD & @LCM \\\hline +24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ +15 & 10 & 25 & & \\ +16 & 12 & 15 & & \\ +\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline +\multicolumn3{|c||}{@Numbers}& @GCD & @LCM \\\hline +24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ +15 & 10 & 25 & & \\ +16 & 12 & 15 & & \\ +\hline +\end{spreadtab} +\end{center} + +\subsubsection{Scientific notation} +The macro function `scitodec' converts a number written in scientific notation into a decimal number, understandable by \ST to achieve its calculations. The syntax is \verbinline-scitodec()-, where \verb-- is: +\begin{itemize} + \item a sequence of characters with the syntax \verb-EE- where \verb-- is a decimal number and the \verb-- is an integer. The `EE' may be written uppercase or lowercase. + + \verb-EE- means the number $\text{\ttfamily }\times10^{\text{\ttfamily }}$ + \item a reference to the \emph{textual} field of a cell containing \verb-EE- +\end{itemize} +Example : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|r|}}\hline +@Scientific notations & @Decimal notations \\\hline +@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ +@-3.1EE-3 & \\ +@15ee5 & \\ +@-0.025ee7 & \\ +@2.125EE0 & \\ +@3.1575EE-4 & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|r|}}\hline +@Scientific notations & @Decimal notations \\\hline +@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ +@-3.1EE-3 & \\ +@15ee5 & \\ +@-0.025ee7 & \\ +@2.125EE0 & \\ +@3.1575EE-4 & \\\hline +\end{spreadtab} +\end{center} + +\subsubsection{Identity} +The simplest macro function is `\verbinline=id()='. It returns the number in its argument. Mathematically, it is not very useful, but with \ST, it makes possible the writing of mathematical expressions in arguments of macro functions where they are not otherwise allowed -- in the argument of \verbinline=sum= for example. + +In the code below, the \verbinline-id- macro function is used to compute the range of cells to add with \verbinline-sum-. In this example, the numeric field of the cell `a2' contains 8. Therefore, `\verbinline=sum([0,-1]:[id(a2-1),-1])/a2=' is equivalent to \verbinline=sum([0,-1]:[7,-1])/8=: + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{r*{10}c}} + @Integers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ +Mean of the :={8} first integers & sum([0,-1]:[id(a2-1),-1])/a2 \\ +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{r*{10}c}} + @Integers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ +Mean of the :={8} first integers & sum([0,-1]:[id(a2-1),-1])/a2 \\ +\end{spreadtab} +\end{center} + +\subsection{Tests} +Three macro-functions provide tests:\par\nobreak +\begin{center} +\verbinline=ifeq(number1,number2,number3,number4)=\par +\verbinline=ifgt(number1,number2,number3,number4)=\par +\verbinline=iflt(number1,number2,number3,number4)= +\end{center} +\falseverb{number1} and \falseverb{number2} are compared: +\begin{itemize} + \item for \verbinline-ifeq-, is \falseverb{number1} = \falseverb{number2}? + \item for \verbinline-ifgt-, is \falseverb{number1} > \falseverb{number2}? + \item for \verbinline-iflt-, is \falseverb{number1} < \falseverb{number2}? +\end{itemize} +If the test is positive, \falseverb{number3} is returned, otherwise it is \falseverb{number4}. + +Here are some values of the function +$f(x)=\begin{cases} +10 &\text{if }x<1\\ +0 &\text{if }x=1\\ +-10 &\text{if }x>1 +\end{cases} +$\smallskip + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*2c|}}\hline +@$x$ & @$f(x)$ \\\hline +-0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*2c|}}\hline +@$x$ & @$f(x)$ \\\hline +-0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline +\end{spreadtab} +\end{center} + +\subsection{Macro-functions manipulating dates} +\subsubsection{Date to number with \ttfamily engshortdatetonum}\label{datetonum} +The macro \verbinline-engshortdatetonum- converts a short date like 1789/7/14 to an integer which is the number of days passed since the 1st March of the year 0\footnote{This year 0 does not exist but this should not be a problem with recent dates.}. It is important to note that this macro-function requires a \emph{textual} argument and not a number or the result of a mathematical calculation. Therefore, if the argument of this macro-function refers to a cell, that cell \emph{must} be a text cell, i.e. a cell containing `\verb-@-' or `\verb-:={}-'. + +In the example below, the first two lines show how to refer to a text cell. The third line displays the date 0 on the left, and more interesting on the right, it shows how to calculate the number corresponding to the current date with the use of the \TeX{} counters \verbinline-\year-, \verbinline-\month- and \verbinline-\day- which contain the numbers of the current year, month and day.\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} +@1789/7/14 & engshortdatetonum(a1)\\ +2001/1/1 :={} & engshortdatetonum(a2)\\\hline +engshortdatetonum(0/3/1) & engshortdatetonum(\number\year/\number\month/\number\day) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{cc}} +@1789/7/14 & engshortdatetonum(a1)\\ +2001/1/1 :={} & engshortdatetonum(a2)\\\hline +engshortdatetonum(0/3/1) & engshortdatetonum(\number\year/\number\month/\number\day) +\end{spreadtab} +\end{center} +Another macro-function provides the same feature but with a long date like `December 25, 1789' or the string contained in \verbinline-\today-:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} +englongdatetonum(February 13, 2005) & englongdatetonum(\today)\\ +@July 1, 1970 & englongdatetonum(a2) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{cc}} +englongdatetonum(February 13, 2005) & englongdatetonum(\today)\\ +@July 1, 1970 & englongdatetonum(a2) +\end{spreadtab} +\end{center} + +\subsubsection{From a number to a date} +Several macro-functions translate a number into a date. All these macro-functions have in common that their result is \emph{text}. Therefore, the cells containing such results \emph{become cells containing text} and if the cell is composed of two fields, the numeric field becomes empty and `\verb-:={}-' is replaced by its result in the text field. + +These macro-functions are: +\begin{itemize} + \item \verbinline-numtoengshortdate- translate a number into a short date like `1789/7/14'; + \item \verbinline-numtoenglongdate- translate a number into a long date like `July 14, 1789'; + \item \verbinline-numtoengmonth- given a number representing a date, it finds the name of the month; + \item \verbinline-numtoengday- same as above but it finds the name of the day. +\end{itemize} +Here is an example in which we consider 1000 days before and 1000 days after 2009/6/1. For each of these 2 dates, we calculate the short date, long date, month and day of the week.\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} \hline +\multicolumn{2}{|c|}{@2009/6/1} \\\hline\hline +1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ +1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ +1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ +1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) \\\hline +-1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ +-1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{cc}} \hline +\multicolumn{2}{|c|}{@2009/6/1} \\\hline\hline +1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ +1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ +1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ +1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) \\\hline +-1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ +-1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) +\end{spreadtab} +\end{center} + +\subsection{Coordinate macro functions}\label{tag} +Rather than referring to a cell by its coordinates which are difficult to remember and change if you insert a row or column, it is sometimes more convenient to give a name to a cell and refer to it later by name. + +The macro function `\verbinline-tag()-' gives a name to the cell in which it is located. This is not really a macro function like the others, since it returns nothing when put in a formula and disappears without causing any effect on the mathematical result. We can write `\verbinline-tag()-' \emph{anywhere} in the numeric field of a cell. The \verb-- can be any string of alphanumeric characters, but it is not advisable to put a letter and a number that could be understood as a reference to a cell, and would therefore be modified at a copy operation with \verbinline-\STcopy-. This macro function has an additional action, it saves via a \verbinline-\def- the numeric value of the cell in which it is located in order to be able to use later \emph{outside} the table via the purely expandable command \verbinline-\STtag{}-. + +Later in the table, instead of writing the coordinates of the cell, we can write `\verbinline-cell()-', which is a macro function that returns the coordinates of the cell named \verb--. For example, if `\verbinline-tag()-' is written in the cell `\verb-B3-' and in a further cell, we write `\verbinline-cell()-', this macro function returns \verb-B3-. + +Here is an example where we add cells and the name `\verb-foo-' is given to the first number and the name `\verb-bar-' to the last. One can see that \verbinline-tag(foo)- is between `1' and `9' but at the end, since this macro function diappears, the numeric field of the cell will be `19': + +\begin{minipage}{0.6\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{r@{}r}} + & 15tag(foo) \\ +@+ & 37 \\ +@+ & 13 \\ +@+ & 48 \\ +@+ & 1tag(bar)9 \\\cline{2-2} + & sum(cell(foo):cell(bar))tag(baz) +\end{spreadtab} + +foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} +\end{lstlisting} +\end{minipage}\kern6pt% +\begin{minipage}{0.3\linewidth} +\begin{spreadtab}{{tabular}{r@{}r}} + & 15tag(foo) \\ +@+ & 37 \\ +@+ & 13 \\ +@+ & 48 \\ +@+ & 1tag(bar)9 \\\cline{2-2} + & sum(cell(foo):cell(bar))tag(baz) +\end{spreadtab} + +foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} +\end{minipage} + +To transmit values between tables computed by \ST\footnote{As requested on \href{https://tex.stackexchange.com/questions/210881}{\texttt{\textbf{tex.stackexchange}}}}, it is possible to tag the cell in the first array using the macro function \verbinline|tag ()|, then in the 2nd array, to call up the previously tagged value with \verbinline|value()|. + +\begin{minipage}{.6\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} + 100 & a1+1tag{abcd} +\end{spreadtab} + +\begin{spreadtab}{{tabular}{c}} + value{abcd} +\end{spreadtab} +\end{lstlisting} +\end{minipage}\kern6pt +\begin{minipage}{.3\linewidth} +\begin{spreadtab}{{tabular}{cc}} + 100 & a1+1tag(abcd) +\end{spreadtab} + +\begin{spreadtab}{{tabular}{c}} + value(abcd) +\end{spreadtab} +\end{minipage} + +When the environment \ST is nested in another environment, the assignments made by the macro funtion \verbinline-tag- are \emph{local} in this environment and could not be accessed outside of this environment via \verbinline-\STtag-. In the example below, the table made with \ST is in a \verbinline-center- environment and we must use \verbinline-\STmakegtag{}- to make global the previous saving of the numerical value contained in the cell marked by `tag()': + +\begin{minipage}{.6\linewidth} +\begin{lstlisting} +\begin{center} + \begin{spreadtab}{{tabular}{cccc}}\hline + 6&9&17&21\\\hline + \multicolumn{4}{c}{average = :={sum(a1:d1)/4tag(avg)}} + \end{spreadtab} + \STmakegtag{avg} +\end{center} +The average is \STtag{avg}. +\end{lstlisting} +\end{minipage}\kern6pt +\begin{minipage}{.3\linewidth} +\begin{center} + \begin{spreadtab}{{tabular}{cccc}}\hline + 6&9&17&21\\\hline + \multicolumn{4}{c}{average = :={sum(a1:d1)/4tag(avg)}} + \end{spreadtab} + \STmakegtag{avg} +\end{center} +The average is \STtag{avg}. +\end{minipage} + +The argument of \verbinline-\STmakegtag- can be made of several names, separated with commas. + +Although at first sight less useful, \ST also provides the macro functions `\verbinline-row()-' and `\verbinline-col()-' that return the number of the row or column of the cell \verbinline-tag()-. Here is an example of how to calculate the average of a number of values; the first and last values are tagged `first' and `last' and therefore, the number of values is row(last)-row(first)+1: + +\begin{minipage}{0.6\linewidth} +\begin{lstlisting} +average = \begin{spreadtab}{{tabular}[b]{r}} +7tag(first)\\9\\15\\6\\20\\13\\11\\55tag(last)\\ +\hline +sum(cell(first):cell(last))/(row(last)-row(first)+1) +\end{spreadtab} +\end{lstlisting} +\end{minipage}\hfill +\begin{minipage}{0.35\linewidth} +average = \begin{spreadtab}{{tabular}[b]{r}} +7tag(first)\\9\\15\\6\\20\\13\\11\\55tag(last)\\ +\hline +sum(cell(first):cell(last))/(row(last)-row(first)+1) +\end{spreadtab} +\end{minipage} + +\section{Particular care} +\subsection{Defining new commands with \ttfamily\textbackslash hline} +It may be useful to define a new command to produce, for example, a double horizontal line:\par\nobreak +\begin{center} +\verbinline-\newcommand\dline{\hline\hline}- +\end{center} +and then try to use it in a table as in this simple example that computes the Fibonnacci sequence in the second line: +\begin{center} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{center} +But, if you write the following code, there is a problem when compiling:\par\nobreak +\begin{lstlisting} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +1 & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{lstlisting} +In the log file, you can read that \verb-\FPeval- fails and complains:\par +\hfill\falseverb{! Improper alphabetic constant.}\hfill\null + +The reason is simple, \verb-\dline- in line 4 is not recognized by \ST as a horizontal rule and therefore, \emph{it is placed in the cell in the next line}. For \ST, the cell \falseverb{b1} contains:\par +\hfill\falseverb{\dline 1}\hfill\null + +Since there is no \verb-@- or \verb-:={}-, \ST considers that the whole cell is a numeric field and \verb-\FPeval- tries valiantly to calculate this content and obviously fails. + +To compile without error, the cell \falseverb{a2} \emph{must} contain a numeric field marker:\par\nobreak +\begin{lstlisting} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{center} + +\subsection{The use of {\ttfamily\textbackslash multicolumn} and \ttfamily\textbackslash SThidecol} +Firstly, in normal use, joint use of \verbinline |\multicolumn| and \verbinline-\SThiderow- should not happen, and most users should not encounter this situation and should not read this section. + +For the brave here is the problem: first, a hidden column \emph{must not} contain a cell with the command \verbinline-\multicolumn-! But what happens if a hidden column hides cells merged with \verbinline-\multicolumn-? + +In general, there is no compilation error or error messages, but there are some subtleties about the references that are a bit turned upside down in the line after the \verbinline-\multicolumn- command\ldots + +Let's take an example, and let's say that, in the following table, we want to merge the cell \falseverb{b2} to \falseverb{h2} and we also want to hide the colomns \falseverb{c}, \falseverb{d} and \falseverb{f}, here in gray:\par\nobreak +\begin{center} +\ttfamily +\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|} +\hline + a1 & b1 & \cellcolor[gray]{0.6}c1 & \cellcolor[gray]{0.6}d1 & e1 & \cellcolor[gray]{0.6}f1 & g1 & h1 & i1 & j1\\\hline + a2 & \multicolumn1c{b2} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1c{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{c}{} & \multicolumn1{c|}{} & i2 & j2\\\hline +\end{tabular} +\end{center} +There are 4 visible merged cells, so we write \verbinline-\multicolumn{4}- because hidden columns are never taken into account when counting the number of \verbinline-\multicolumn-. + +Then we count 4 letters from \falseverb{b} (this letter included): we obtain the letter \falseverb{e}. In the range \falseverb{b-e}, let's count: 2 gray hidden columns are included (\falseverb c and \falseverb d) and 1 hidden column is not included (\falseverb f). These numbers are important to understand the following, also let's call them $x$ and $y$ in the general case. + +The rule is: +\begin{itemize} + \item it is necessary to add $y$ signs \verb-&- after \verbinline-\multicolumn- (in the example above, it would be 1); + \item references to columns of cells after the \verbinline-\multicolumn- will be shifted $x$ to the beginning of the alphabet. For the example given, if we want to refer to the cell \falseverb{i2}, we should write \falseverb{g2} instead of \falseverb{i2}. +\end{itemize} +Here is an example with a similar structure to the previous ($x=2$ and $y=1$) with simple formulas: add 1 to the number above.\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*{7}{c|}}} +\hline +1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline +a1+1& \multicolumn4{l|}{:={b1+1}} & & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*{7}{c|}}} +\hline +1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline +a1+1& \multicolumn4{l|}{:={b1+1}} & & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline +\end{spreadtab} +\end{center} +And another example with $x=1$ and $y=0$ where a single column is hidden \falseverb d:\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*{9}{c|}}} +\hline +1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline +a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*{9}{c|}}} +\hline +1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline +a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline +\end{spreadtab} +\end{center} + +\subsection{Messages delivered by \ST} +The package delivers error messages and aborts compilation in these cases: +\begin{itemize} + \item a circular reference is found in a cell. In this case, the dependent cells are displayed; + \item a cell refers to an empty cell or a text cell when a non-empty numeric field is expected; + \item a cell refers to an undefined cell (outside the table); + \item a cell refers to a cell merged by a \verbinline-\multicolumn- command; + \item a relative reference has bad syntax. +\end{itemize} +The package can deliver informative messages (in the log file), which it does by default. If the user wants or not the delivery of informative messages, the syntax is \verbinline-\STmessage{true}- or \verbinline-\STmessage{false}-. + +To understand the meaning of these messages, let's take a simple table:\par\nobreak +\begin{minipage}{0.65\linewidth} +\begin{lstlisting} +\STmessage{true}% already set by default +\begin{spreadtab}{{tabular}{|cccc|c|}}\hline +b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.35\linewidth} +\centering +\begin{spreadtab}{{tabular}{|cccc|c|}}\hline +b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline +\end{spreadtab} +\end{minipage} + +Here are the messages deliverd by \ST:\par\nobreak +\begin{lstlisting} +[spreadtab] New spreadtab {tabular}{|cccc|c|} +* reading tab: ok +* computing formulas: + cell A1-B1-C1 + cell B1 + cell C1 + cell D1 + cell E1 +* building tab: ok +[spreadtab] End of spreadtab +\end{lstlisting}\medskip +Preceded by a star, we recognize the 3 steps necessary for \ST to complete its task: reading the table, calculation of the formulas and building the final table. + +For the second step, cells are evaluated from top to bottom, left to right: at line 4 in the code above, \ST says that it begins by trying to calculate the first cell \falseverb{A1}. After a dash, we see that for this, it must first compute the cell \falseverb{B1}, which itself requires that the cell \falseverb{C1} is calculated: the latter can be calculated since it depends only on \falseverb{D1} which is a cell containing the number 10. + +In the following (lines 5 to 8), there is only one cell per line which means that when \ST tries to evaluate the cell, either it contains a number or dependent cells are already calculated. + +\subsection{Debug mode} +To ease the use of \ST, a debug mode is available. It is activated when the command \verbinline-\STdebug- is written in the optional argument of the \verbinline-spreadtab- environment. This command changes the behavior of \ST which, instead of displaying the final table, displays one (or more) table(s) containing debugging information. This display is done just after \ST has read all the cells, and no calculating of formulas has yet taken place. There are as many tables as commands \verbinline-\STdebug-, provided that their argument is different. Only 3 arguments are possible: +\begin{itemize} + \item \verbinline-\STdebug{formula}-: displays all the numeric fields and the ends of lines; + \item \verbinline-\STdebug{text}-: displays all the textual fields; + \item \verbinline-\STdebug{code}-: displays the internal code of the cells. Indeed, \ST assigns a code to every cell when it reads the table. Here are the possible values of this code: + \begin{enumerate}[label=\small\textbullet] + \item $-1$ if the cell is merged with \verbinline-\multicolumn-; + \item 0 if the cell is a text cell or is empty; + \item 1 if the numeric field of the cell contains a formula which will be computed later; + \item 2 if the numeric field of the cell contains a number. + \end{enumerate} +\end{itemize} + +When the `debug mode' is activated, the final table is not displayed. + +Here is a table which will be used for the next example: + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|r|r|}}\hline +@$x$ &@$y$ & @$x+y$\\\hline\hline +22 & 54 & \STcopy{v3}{a2+b2} \\ +43 & 65 & \\ +49 & 37 & \\\hline +$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline +\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|r|r|}}\hline +@$x$ &@$y$ & @$x+y$\\\hline\hline +22 & 54 & \STcopy{v3}{a2+b2} \\ +43 & 65 & \\ +49 & 37 & \\\hline +$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline +\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} +\end{spreadtab} +\end{center} +Let's ask \ST to show the 3 possible debugging tables for the table above. To do this, just change line 1 in the code above to: + +\hfill\verbinline[basicstyle=\ttfamily\small]-\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline-\hfill\kern0pt +\begin{center} +\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline +@$x$ &@$y$ & @$x+y$\\\hline\hline +22 & 54 & \STcopy{v3}{a2+b2} \\ +43 & 65 & \\ +49 & 37 & \\\hline +$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline +\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} +\end{spreadtab} +\end{center} +These 3 debugging tables may help to better understand what happens behind the scene when \ST works. We can observe that all cells with a numeric field (see table 2) have an internal code of 1 or 2 (see table 3) and an associated numeric field marker `\verb-:=-' in table 1. This marker represents the location where (by substitution) the result of the numeric field will be inserted. So from the contents of text fields in table 1 and, once calculated, the numeric fields, by a simple substitution, the cells are reconstituted to give those of the final table. + +In the debugging tables, cells containing the coordinates are grayed if the package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/colortbl/}{\texttt{\textbf{colortbl}}} has been loaded; they are left white otherwise. + +\section{Examples} +In the examples of this section, the numbers entered by the user are in \textcolor{black}{red} and the calculated numbers are in \textcolor{black}{black} + +In these tables, lots of tricks (struts, \verbinline-\multicolumn- commands) and packages (including the numprint package and its columns `N', which aligns the decimal points) were used to obtain a satisfactory result. The code is sometimes cumbersome and difficult to read, but these tables are not basic but well-groomed examples! + +\subsection{Pascal's triangle again!} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*7r}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ +[0,1] & [-1,1] & & & & & \\ +\color{red}:={1}& & & & & & +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{*7r}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ +[0,1] & [-1,1] & & & & & \\ +\color{red}:={1}& & & & & & +\end{spreadtab} +\end{center} + +\subsection{The convergence of a series} +For people familiar with maths, here is the series of the exponential. Indeed, +\[\forall x\in \mathbf{R}\qquad e^x=\sum_{k=0}^\infty\frac{x^k}{k!}\] +and this table shows the speed of convergence for $x=0.5$ +\begin{lstlisting} +\STautoround{15} +\renewcommand\STprintnum[1]{\numprint{#1}} +\begin{spreadtab}{{tabular}{cc}} +\multicolumn{2}{c}{Convergence at $x=\color{red}:={0.5}$}\\[1.5ex] +@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline +\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ +\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STautoround{15} +\renewcommand\STprintnum[1]{\numprint{#1}} +\begin{spreadtab}{{tabular}{cc}} +\multicolumn{2}{c}{Convergence at $x=\color{red}:={0.5}$}\\[1.5ex] +@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline +\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ +\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\\hline +\end{spreadtab} +\end{center} + +\subsection{Convergence to the golden ratio} +In mathematical terms, the sequence $F_n$ of Fibonacci numbers is defined by the recurrence relation:\[F_0=1\qquad F_1=1\qquad F_{n+2}=F_{n+1}+F_n\] + +The golden ratio is the limit of the ratios of successive terms of the Fibonacci sequence. We show here that the quotients $F_{n+1}/F_n$ approximate the golden ratio $\varphi=\frac{1+\sqrt{5}}{2}$ alternately lower and higher than $\varphi$.\par\nobreak +\begin{lstlisting} +\STautoround{9} +$\begin{spreadtab}{{array}{ccN39N{3}{9}}} +@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline +\color{red}:=1 & \color{red}:=1 & & \\ +\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ + & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\\hline +\end{spreadtab}$ +\end{lstlisting} +\begin{center} +\STautoround{9} +$\begin{spreadtab}{{array}{ccN39N{3}{9}}} +@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline +\color{red}:=1 & \color{red}:=1 & & \\ +\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ + & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\\hline +\end{spreadtab}$ +\end{center} + +\subsection{A billing table} +Here is a billing table where the decimal points are aligned in columns with the column specifier `N' of the package \falseverb{numprint}. + +This table is generated by the environment \verb=tabularx= stretched to fit 80\% of the width of the line. The command \verbinline=\multicolumn= has been widely used for formatting:\par\nobreak +\begin{lstlisting} +\nprounddigits2 +\let\PC\% +\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} +\newcommand\RED{\color{red}} +\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} +\hline +@Item &@\multicolumn1c{Price/U}& @\multicolumn1c{Qty} & @\multicolumn1c{Price} & @\multicolumn1c{Reduction} & @\textbf{Net}\\\hline +@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline +@\multicolumn6c{}\\[-1.5ex]\cline{4-6}% empty line and raise it a little +@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ +\cline{4-6} +\end{spreadtab} +\end{lstlisting} +\begin{center} +\nprounddigits2 +\let\PC\% +\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} +\newcommand\RED{\color{red}} +\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} +\hline +@Item &@\multicolumn1c{Price/U}& @\multicolumn1c{Qty} & @\multicolumn1c{Price} & @\multicolumn1c{Reduction} & @\textbf{Net}\\\hline +@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline +@\multicolumn6c{}\\\cline{4-6}% empty line +@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ +\cline{4-6} +\end{spreadtab} +\end{center} + +\subsection{A magic square} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} +\hline +\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline +2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline +4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} +\hline +\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline +2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline +4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline +\end{spreadtab} +\end{center} + +\subsection{A pyramid of additions} +Each number is the sum of two numbers located below it. +\begin{lstlisting} +\newlength\cellsize +\setlength\cellsize{1.5cm} +\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} +\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} +\cline{4-5} +&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} +&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} +&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline +\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\newlength\cellsize +\setlength\cellsize{1.5cm} +\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} +\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} +\cline{4-5} +&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} +&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} +&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline +\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline +\end{spreadtab} +\end{center} +\medskip +\parskip0pt +\begin{center} +$\star$\par +$\star\quad\star$ +\end{center}\bigskip +That's all. I hope you will find this package useful!\par\nobreak\medskip + +I thank you in advance for sending by \href{mailto:unbonpetit@netc.fr}{\texttt{\textbf{email}}} any bug you find, any macro-function or improvment you would like to be implemented, assuming that it must be \emph{realistic}. This package has to be modest and \ST is not excel or calc: it is impossible to implement some advanced features of these spreadsheets.\par\nobreak\bigskip +Christian \textsc{Tellechea} +\end{document} \ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.pdf b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.pdf new file mode 100644 index 00000000000..ed5d35618ab Binary files /dev/null and b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.pdf differ diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.tex b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.tex new file mode 100644 index 00000000000..ecf1f4e2860 --- /dev/null +++ b/Master/texmf-dist/doc/latex/spreadtab/spreadtab-fr.tex @@ -0,0 +1,1594 @@ +% Documentation de l'extension "spreadtab" +\documentclass[french,a4paper,10pt]{article} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[a4paper,margin=2.6cm]{geometry} +\usepackage[table]{xcolor} +\usepackage{amsmath,amssymb,textcomp,array,arydshln,tabularx,listings,numprint,xspace,spreadtab,fancyhdr,libertine,babel,enumitem} +\usepackage[italic]{mathastext} +\usepackage[scaled=0.8]{luximono} +\fancyhead[L]{} +\fancyhead[C]{\small\bfseries\ST} +\fancyhead[R]{\scriptsize\slshape \leftmark} +\fancyfoot[l]{} +\fancyfoot[c]{} +\fancyfoot[r]{\thepage} +\usepackage[bottom]{footmisc} +\usepackage[protrusion=true,final,verbose=true,babel=true]{microtype} +\frenchbsetup{StandardLists=true} +\makeatletter +\definecolor{ST@bckgcolor}{rgb}{0.87,0.9,1} +\definecolor{ST@codebckgcolor}{rgb}{0.9,0.9,0.9} +\definecolor{ST@keywordstc}{rgb}{0.7,0,0} +\definecolor{ST@keywordslatex}{rgb}{0,0,1} +\definecolor{ST@arguments}{rgb}{0,0,0} +\definecolor{ST@comments}{rgb}{0.5,0.5,0.5} +\lstset{% + language=[AlLaTeX]TeX,float=hbp,basicstyle=\footnotesize\ttfamily,identifierstyle=\color{ST@arguments},% + keywordstyle=\color{ST@keywordslatex},commentstyle=\itshape\color{ST@comments},% + columns=fixed,tabsize=4,frame=single,extendedchars=false,% + showspaces=false,showstringspaces=false,numbers=left,numberstyle=\tiny\ttfamily,% + breaklines=true,breakindent=3em,backgroundcolor=\color{ST@bckgcolor},breakautoindent=true,% + captionpos=t,xleftmargin=1em,xrightmargin=1em,lineskip=0pt,% + numbersep=1em,classoffset=1,% + morekeywords={% les macros et commandes de spreadtab + spreadtab,endspreadtab,SThiderow,SThidecol,STsavecell,STautoround,STmessage,STsetdecimalsep,STtransposecar,STdebug,STdisplaytab,STsetdisplaymarks,% + STnumericfieldmarker,STprintnum,STtextcell,STcopy,STtag,STmakegtag,STeol,fact,id,ifeq,ifgt,iflt,numtofrshortdate,% + numtoengshortdate,numtofrlongdate,numtoenglongdate,numtofrmonth,% + numtoengmonth,numtofrday,numtoengday,sum,rand,randint,sumprod,% + frshortdatetonum,engshortdatetonum,englongdatetonum,frlongdatetonum,gcd,lcm,tag,cell,row,col,value},% + keywordstyle=\color{ST@keywordstc},classoffset=0} + +%%%%%%%%%%% environnement OOcalc +\newcount\cntlin +\newcount\cntcol + +\newtoks\t@b +\long\def\ifremain@lines#1\\#2\@nil{% + \csname @\ifx\@empty#2\@empty second\else first\fi oftwo\endcsname} +\long\def\subst@eol#1\\#2\@nil{\addtot@b{#1\\\cline{1-1}\hdashline}% + \ifremain@lines#2\\\@nil{\addtot@b&\subst@eol#2\@nil}{\addtot@b{#2\end{tabular}}}} +\long\def\collect@body#1\end{\subst@eol#1\@nil\end} + +\newcommand\addtot@b[1]{\t@b\expandafter{\the\t@b#1}} +\newcommand\edftot@b[1]{\edef\temp@{#1}\expandafter\addtot@b\expandafter{\temp@}} + +\newenvironment{OOocalc}[2][1.5cm]{% #1=largeur colonnes #2 = nombre de colonnes + \newcolumntype w{>{\centering\arraybackslash}m{#1}}% + \arrayrulewidth0.4pt\dashlinedash0.4pt\relax\dashlinegap3pt + \global\cntlin\m@ne\global\cntcol\z@ + \tabfont + \tabcolsep0pt + \t@b{\begin{tabular}{% + |>{\cellcolor{tabheadcolor}% + \global\cntcol\z@\global\advance\cntlin\@ne + \centering\arraybackslash + \ifnum\cntlin>\z@\tableheadformat\number\cntlin\fi} + m{2em}|*{#2}{w:}}% + \hline + \rowcolor{tabheadcolor}}% + \loop + \ifnum\cntcol<#2 + \advance\cntcol\@ne + \addtot@b{&\multicolumn{1}{>\centering m{#1}|}}% + \edftot@b{{\noexpand\tableheadformat\@Alph\cntcol}}% + \repeat + \addtot@b{\\\hline&}% + \collect@body}{\the\t@b} + +\def\longfrdate@i#1/#2/#3\@nil{\number#3\relax\ifnum#3=1 \ier\fi\space\ifcase #2 \or janvier\or février\or mars\or avril\or mai\or juin\or juillet\or aout\or septembre\or octobre\or novembre\or décembre\fi\space#1} +\def\longfrdate{\expandafter\longfrdate@i\STdate\@nil} +\makeatother + +% commandes de personnalisation de OOcalc +\newcommand*\tabfont{\fontfamily{phv}\selectfont\footnotesize}% police du tableau (helvetica ici) +\newcommand*\tableheadformat{\bfseries}% police des en-têtes du tableau (en gras) +\colorlet{tabheadcolor}{gray!40}% couleur de font des en-têtes du tableau +\colorlet{palepink}{pink!80} +\colorlet{lightpink}{pink!30} +\colorlet{palegreen}{green!60} +\colorlet{lightgreen}{green!30} +\newcommand\CC[1]{\cellcolor{#1}} + +\newcommand\verbinline[1][]{\lstinline[breaklines=false,basicstyle=\normalsize\ttfamily,#1]} +\newcommand\ST{\textsf{\STname}\xspace} +\newcommand\falseverb[1]{\texttt{\detokenize{#1}}} + +\usepackage[bookmarks=true,bookmarksopen=true,colorlinks=true,hyperfootnotes=false,filecolor=black,linkcolor=blue,urlcolor=magenta,pdfauthor={Christian TELLECHEA},pdftitle={spreadtab},pdfsubject={Spreadtab permet d'utiliser des fonctionnalités de tableur dans un tableau avec LaTeX},pdfkeywords={spreadtab},pdfcreator={LaTeX}]{hyperref} + +\begin{document} +\parindent0pt\pagestyle{fancy}\setitemize{leftmargin=3em,topsep=0pt,parsep=0pt,itemsep=0pt,label=--}\STsetdecimalsep{,} +\begin{titlepage} + \null\par\vfill + \begin{center} + \begin{minipage}{0.75\linewidth} + \begin{center} + \Huge\bfseries\ST\par\vspace{5pt} + \small v\STver\par\vspace{35pt} + \normalsize Manuel de l'utilisateur + \end{center} + \end{minipage} + \end{center} + \vspace{1cm} + \begin{center} + Christian {\sc Tellechea}\par\small + \href{mailto:unbonpetit@netc.fr}{\texttt{\textbf{unbonpetit@netc.fr}}}\par\vspace{5pt} + \longfrdate + \end{center} + \vfill + \begin{center} + \begin{minipage}{0.8\linewidth} + \noindent\hrulefill\par + \hfill\textbf{\textit{Résumé}}\hfill{}\medskip\par\footnotesize + Cette extension permet d'utiliser des fonctionnalités de tableur dans n'importe quel environnement \og tableau\fg{} avec \LaTeX{}.\par\smallskip + La principale fonctionnalité étant de pouvoir écrire des formules dans les cellules d'un tableau qui font références à d'autres cellules, de calculer les formules contenues dans les cellules et d'afficher les résultats numériques de ces formules dans le tableau.\par + \hrulefill + \end{minipage} + \end{center} + \vfill{} +\end{titlepage} + +\tableofcontents\newpage +\parskip\medskipamount +\section{Introduction} + +\subsection{Présentation} +Cette extension permet de construire des tableaux similaire à des feuilles de calculs. Les cellules du tableau ont des coordonnées (colonne et ligne) qui peuvent être utilisées dans des formules pour calculer des valeurs dans d'autres cellules. + +Ce package nécessite le moteur $\varepsilon$-\TeX, le format \LaTeXe{} ainsi que le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} à qui sont confiés les calculs. Le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/xstring/}{\texttt{\textbf{xstring}}} est également requis dans une version \emph{supérieure ou égale} à la version \verb-v1.5d [2010/03/28]-. + +J'ai souhaité dès le départ de rendre ce package compatible avec \emph{tous} les environnements de tableaux, sous réserve que les séparateurs entre colonnes soient \og\verb=&=\fg{} et les retours à la ligne soient \og\verb=\\=\fg{}. Cette contrainte forte sur la compatibilité m'a conduit à programmer \ST pour qu'il agisse d'une façon \emph{totalement indépendante} de l'environnement tableau. Ainsi, la lecture du tableau, le traitement et le calcul des formules se fait \emph{avant} que l'environnement tableau ne prenne la main et ne \og voit\fg{} le corps du tableau. + +Par conséquent, \ST procède en 3 étapes : +\begin{itemize} + \item en premier lieu, \ST lit le corps du tableau et le divise en lignes puis en cellules en reconnaissant dans chacune la présence d'une éventuelle formule; + \item ensuite, il procède au calcul des formules contenues dans les cellules, en ayant pris soin pour chacune de calculer auparavant les cellules dépendantes. L'ordre dans lequel les cellules doivent être calculées est déterminé par \ST. Les calculs sont faits par le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}}; + \item enfin, il faut reconstruire le tableau en ayant remplacé chaque formule par la valeur numérique préalablement calculée et passer la main à l'environnement tableau spécifié par l'utilisateur. +\end{itemize} +Les deux syntaxes possibles (et équivalentes) sont les suivantes, où \verb-- représente le nom de n'importe quel environnement de type tableau disponible avec \LaTeX{} ou avec une extension :\par\nobreak +\begin{minipage}{0.48\linewidth} +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\begin{spreadtab}{{}{}} + tableau avec formules et nombres +\end{spreadtab} +\end{lstlisting} +\end{minipage}\hfill ou\hfill +\begin{minipage}{0.48\linewidth} +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\spreadtab{{}{}} + tableau avec formules et nombres +\endspreadtab +\end{lstlisting} +\end{minipage} + +et après le travail de \ST, on obtient un affichage comme si l'on avait écrit :\par\nobreak +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\begin{}{} + tableau avec nombres +\end{} +\end{lstlisting} + +Même si disposer de fonctionnalités ressemblant à celles d'un tableur avec \LaTeX{} est appréciable, il ne faut pas perdre de vue que les 3 étapes décrites ci-dessus prennent du temps et surtout que \falseverb{fp} est lent dans ses calculs. L'ensemble conduit donc à des temps de compilation \emph{beaucoup plus importants} qu'avec un tableau classique. + +Il faut ajouter que \ST \emph{ne peut remplacer un tableur}. En effet, ses possibilités sont très limitées. De plus, surtout pour des tableaux complexes ou de grande taille, le manque d'aide visuelle devient gênant\footnote{Ceci dit, je certifie qu'avec l'habitude, cette gêne tend à s'estomper (si l'on s'en tient à des tableaux raisonnables, bien sûr).}, et la syntaxe de \ST constitue aussi un obstacle supplémentaire. L'avantage de cette extension est de pouvoir écrire \emph{dans le code \LaTeX} des tableaux comportant des calculs, alors que ces tableaux sont généralement exportés\footnote{On peut signaler les 2 principaux programmes d'exportation : \href{http://calc2latex.sourceforge.net/}{\texttt{\textbf{cacl2latex}}} pour \og calc\fg{} de Open Office, et \href{http://www.ctan.org/tex-archive/support/excel2latex/}{\texttt{\textbf{excel2latex}}} pour \og excel\fg{} de Microsoft Office.} d'une feuille de calcul d'un tableur vers le code \LaTeX. On évite ainsi les désagréments des programmes d'exportation : mise en forme souvent à retoucher pour obtenir exactement ce que l'on veut, non compatibilité avec tous les environnements de tableaux, obtention de tableaux ne contenant que les valeurs (les formules sont perdues à l'exportation), exportation à recommencer si l'on modifie un seul nombre ou formule dans le tableau. + +\subsection{Motivation} +Quelques mois avant de commencer à m'attaquer à ce package, Derek \textsc{O'Connor} m'avait fait remarquer que rien n'était disponible dans le monde des extensions de \LaTeX{} pour imiter ---~ne serait-ce qu'un peu~--- le calcul de formules dans des tableaux, comme cela se fait couramment avec des tableurs. J'ai trouvé le défi intéressant et je me suis lancé dans l'écriture de ce package qui en fait, n'est qu'un exercice de programmation. + +La route a été longue avant d'arriver à cette version et je tiens à remercier tout particulièrement Christophe \textsc{Casseau} pour l'intérêt qu'il a porté dès le début à ce travail et les suggestions qu'il m'a faites, ainsi que plus récemment Derek \textsc{O'Connor} pour ses conseils et pour les échanges constructifs que nous avons eus. J'adresse également mes remerciements à Andrew \textsc{Parsloe} pour la relecture et les corrections apportées à la traduction de ce manuel en anglais. + +\section{Fonctionnalités courantes} +Il faut noter tout d'abord qu'à l'intérieur d'un tableau sous environnement \ST, les caractères \og\verb=:=\fg{} et \og\verb=;=\fg{} perdent leur code de catégorie actif qui leur a été attribué si vous utilisez l'option \falseverb{frenchb} du package \falseverb{babel}. Par conséquent, l'espace automatique inséré avant ces caractères sera désactivé dans un tableau. + +\label{STeol}Par défaut, \ST considère qu'une ligne se termine avec ``\verb-\\-'' qui est habituel dans les tableaux. Ce marqueur de fin de ligne peut être modifié via la commande \verbinline-\STeol{}-. On peut par exemple écrire \verbinline-\STeol{\tabularnewline}-. Il faut bien comprendre que les fins de lignes qui seront insérées dans le tableau final seront toujours ``\verb-\\-'', même si le marqueur de fin de ligne lorsque \ST \emph{lit} le tableau a été modifié. + +\subsection{Références absolues} +Dans le tableau, les cellules sont repérées par leur références absolues de cette façon : +\begin{itemize} + \item la colonne est une lettre de \falseverb a à \falseverb z, \falseverb a représentant la 1\iere{} colonne de gauche : on est donc d'emblée limité à 26 colonnes, ce qui devrait suffire pour la grande majorité des cas; la lettre est insensible à la casse, elle peut donc être indifféremment minuscule ou majuscule; + \item à la suite immédiate de la lettre, un nombre entier strictement positif représente le numéro de la ligne, la ligne numéro 1 étant la ligne du haut. +\end{itemize} +Une référence absolue s'écrit donc par exemple : \og\falseverb{b4}\fg{}, \og\falseverb{C1}\fg{} ou \og\falseverb{d13}\fg\footnote{Cette notation se retrouve dans les tableurs : la lettre représente la colonne et le nombre qui suit représente la ligne. Cet ordre est le contraire de la convention utilisée avec les matrices en mathématiques.}. Visuellement, on peut illustrer ce fonctionnement par ce genre de tableau ressemblant à un tableur, ici volontairement limité à 5 lignes et 5 colonnes : +\begin{center} +\begin{OOocalc}[6em]{5} +&&&&\\&&&&\\&&&&\\&&&&\\&&&&\\ +\end{OOocalc} +\end{center} +Voici un exemple où l'on calcule la somme de chaque ligne et de chaque colonne puis, la somme totale :\par\nobreak +\begin{minipage}{0.75\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{rr|r}} +22 & 54 & a1+b1 \\ +43 & 65 & a2+b2 \\ +49 & 37 & a3+b3 \\ +\hline +a1+a2+a3 & b1+b2+b3 & a4+b4 +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.25\linewidth} +\centering +\begin{spreadtab}{{tabular}{rr|r}} +22 & 54 & a1+b1 \\ +43 & 65 & a2+b2 \\ +49 & 37 & a3+b3 \\ +\hline +a1+a2+a3 & b1+b2+b3 & a4+b4 +\end{spreadtab} +\end{minipage}% + +Pour les matheux, voici un autre exemple où l'on calcule quelques lignes du triangle de Pascal :\par\nobreak +\begin{minipage}{0.75\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{ccccc}} +1 & & & & \\ +a1 & a1 & & & \\ +a2 & a2+b2 & b2 & & \\ +a3 & a3+b3 & b3+c3 & c3 & \\ +a2 & a4+b4 & b4+c4 & c4+d4 & d4 +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.25\linewidth} +\centering +\begin{spreadtab}{{tabular}{ccccc}} +1 & & & & \\ +a1 & a1 & & & \\ +a2 & a2+b2 & b2 & & \\ +a3 & a3+b3 & b3+c3 & c3 & \\ +a2 & a4+b4 & b4+c4 & c4+d4 & d4 +\end{spreadtab} +\end{minipage}% + +\subsection{Références relatives} +Pour faire référence à une cellule, il peut être commode de spécifier sa position par rapport à la cellule où se trouve la formule. Ainsi, les coordonnées \og relatives\fg{} d'une cellule sont 2 nombres relatifs écrits selon cette syntaxe : \falseverb{[x,y]}, où \falseverb x est le décalage horizontal par rapport à la cellule contenant la formule et \falseverb y est le décalage vertical. Ainsi, \falseverb{[-2,3]} fait référence à la cellule se trouvant 2 colonnes avant (à gauche) et 3 lignes après (plus bas) la cellule où se trouve la formule. + +Voici à nouveau le triangle de Pascal vu ci-dessus, mais les références sont relatives et l'environnement \og\verbinline-matrix-\fg{} du package \href{http://www.ctan.org/tex-archive/macros/latex/required/amslatex/math/}{\texttt{\textbf{amsmath}}} est utilisé :\par\nobreak +\begin{minipage}{0.82\linewidth} +\begin{lstlisting} +$ +\begin{spreadtab}{{matrix}{}} +1\\ +[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] +\end{spreadtab} +$ +\end{lstlisting} +\end{minipage}\hfill +\begin{minipage}{0.15\linewidth} +\centering +$ +\begin{spreadtab}{{matrix}{}} +1\\ +[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ +[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] +\end{spreadtab} +$ +\end{minipage}% + +On remarque que les références relatives sont plus adaptées ici puisque seulement 2 références différentes sont utilisées : \falseverb{[0,-1]} qui se réfère à la cellule de dessus et \falseverb{[-1,-1]} qui se réfère à la cellule au Nord-Ouest de la cellule où se trouve la formule. + +On peut utiliser dans une même formule un mélange de références absolues et relatives. + +\subsection{Cellules de texte} +Si l'on veut mettre du texte dans une cellule, il faut indiquer à \ST que la cellule ne doit pas être calculée. Il suffit de placer quelque part dans la cellule le caractère \og\falseverb @\fg{}. Ce faisant, la cellule est ignorée par \ST et devient une cellule inerte à qui il n'est pas possible\footnote{Il y a une exception à cette règle, voir la page \protect\pageref{datetonum}.} de faire référence nulle part ailleurs dans le tableau. + +Voici un exemple :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ valeurs de $x$ & -5 & -1 & 4 \\ +@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ valeurs de $x$ & -5 & -1 & 4 \\ +@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline +\end{spreadtab} +\end{center} +Le caractère \og\falseverb @\fg{} est le développement de la séquence de contrôle \verbinline=\STtextcell=. On peut donc redéfinir cette séquence de contrôle en ce que l'on veut et par exemple, \verbinline-\renewcommand\STtextcell{`}- fera qu'une cellule contenant le caractère ``\verb=`='' sera comprise comme étant une cellule de texte. + +De plus, si une cellule est vide ou entièrement constituée d'espaces, alors \ST la considérera comme une cellule de texte. + +\subsection{Cellules mixtes} +En réalité, chaque cellule est composée de \emph{deux} champs. D'un côté le \emph{champ numérique} qui contient la formule et de l'autre le \emph{champ textuel} qui sera ignoré par \falseverb{fp} et n'entre pas en ligne de compte pour les calculs : +\begin{itemize} + \item dans une cellule, si rien n'est précisé, la totalité de la cellule est considérée comme étant le champ numérique, et le champ textuel est vide (c'était le cas pour toutes les cellules du tableau du triangle de Pascal vu précédemment); + \item si la cellule contient \og\falseverb{@}\fg{}, alors la totalité de la cellule est considérée comme étant le champ textuel. Le champ numérique est vide et inaccessible. + \item si la cellule contient \og\verb-:=-\fg, alors l'argument entre accolades qui suit est le champ numérique, et tout le reste est le champ textuel. La cellule a cette structure :\par\smallskip + \hfil\verb-:={champ numérique}-\hfil\null\par\smallskip + On peut changer ce marqueur en la séquence de contrôle \og\verb-\=-\fg{} par exemple, en redéfinissant la macro \verbinline-\STnumericfieldmarker- de cette façon :\par\smallskip{\centering + \verbinline-\renewcommand\STnumericfieldmarker{\=}-\par\smallskip} + Dans ce cas, le développement de \verb-\=- n'aurait strictement aucune importance et n'interviendrait pas dans le processus : pour \ST, il ne s'agit que d'un marqueur de début de formule qui est cherché et reconnu sans être développé. +\end{itemize} +Une fois le \og\verb-champ numérique-\fg{} calculé, lui seul et le marqueur \og\verb-:=-\fg{} seront remplacés par la valeur numérique calculée. + +Il faut noter que \og\verb-:={champ numérique}-\fg{} peut se trouver à l'intérieur d'accolades et ce quelque soit le niveau d'imbrication. Par exemple, dans une cellule, on peut écrire \verb-\textbf{:={a1+1}}-. Si le champ numérique de la cellule \falseverb{a1} est 5, alors la cellule contiendra au final \verb-\textbf{6}-. + +Pour fixer les idées, voici un exemple très simple :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +valeur 1 : :={50} & valeur 2 : :={29} & moyenne : \textbf{:={(a1+b1)/2}}\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +valeur 1 : :={50} & valeur 2 : :={29} & moyenne : \textbf{:={(a1+b1)/2}}\\\hline +\end{spreadtab} +\end{center} +À noter également que \og\verb-:={}-\fg{}, qui définit formule vide, a le même effet que \og\verb-@-\fg dans une cellule : celle-ci est comprise comme cellule de texte. Cependant, \og\verb-@-\fg et \og\verb-:={}-\fg{} \emph{ne sont pas équivalents} car une cellule textuelle contenant ce dernier peut recevoir une formule par copie (voir section suivante), ce qui est impossible avec \og\verb-@-\fg. + +\subsection{Copier des formules} +Pour éviter d'avoir à recopier des formules identiques dans des cellules voisines, \ST fournit l'instruction \verbinline-\STcopy-. + +Cette commande se place dans une cellule selon cette syntaxe : +\begin{center} +\verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formule}- +\end{center} +où $x$ et $y$ sont des nombres positifs qui représentent des décalages horizontaux et verticaux par rapport à la cellule où se trouve l'instruction. La cellule qui contient la commande et la cellule obtenue par ces décalages définissent une plage rectangulaire de cellules qui recevront la \verb--\footnote{La copie ne peut donc se faire que vers des cellules se trouvant à droite et plus bas que la cellule dans laquelle se trouve la commande.}. La commande \verbinline-\STcopy -\emph{ne doit pas} se trouver dans une cellule où un marqueur de champ numérique \og\verb-:=-\fg{} est présent. + +Voici comment se déroule la copie : elle se fait en partant de la cellule où se trouve l'instruction, la cellule source. Pour chaque cellule cible, toutes les références dans la formule sont incrémentées pour tenir compte du décalage entre la cellule cible et la cellule source. Ainsi par exemple, mettons que la cellule source contienne la formule \verb-a1+b2+c3-. Lorsque cette formule est copiée dans une cellule cible se trouvant 2 colonnes à droite et 5 lignes en dessous, cette formule deviendra : \verb-c6+d7+e8-. La formule peut également contenir des références relatives qui, puisqu'elle sont relatives, ne seront pas modifiées. + +En faisant précéder d'un \og\verb-!-\fg une coordonnée d'une référence, cette coordonnée reste inchangée lors de la copie. Reprenons l'exemple précédent avec la formule \verb-a!1+!b2+!c!3-. Si cette formule est copiée dans la cellule se trouvant 2 colonnes à droite et 5 lignes en dessous, alors, elle deviendra : \verb-c1+b7+c3-. Cette fonctionnalité est compatible avec des références relatives : mettons qu'une cellule contienne la formule \verb|[-1,!-1]+[!-1,1]+[!1,!2]| et que cette formule soit copiée vers la cellule se trouvant 2 colonnes à droite et 5 lignes en dessous. Alors, elle deviendra : \verb|[-1,-6]+[-3,1]+[-1,-3]|. + +Le caractère \og\verb-!-\fg est le développement de la séquence de contrôle \verbinline-\STtransposecar-. On peut donc modifier ce caractère en tout autre avec \verbinline-\renewcommand\STtransposecar-\verb-{}-. Le point d'exclamation, utilisé par défaut, garde son code de catégorie actif qui lui a été attribué par le package \verb-babel- chargé avec l'option \verb-frenchb-. + +Dans la syntaxe \verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formule}-, si le nombre $x$ est absent, la copie dans le sens horizontal se fait vers la droite jusqu'au bord droit du tableau. Si $y$ est absent, la copie dans le sens vertical se fait jusqu'en bas du tableau. + +Voici quelques exemples : +\begin{tabular}{cl}\hline +\verb-{>3,v1}- & copie vers les 3 colonnes à droite et 1 ligne en dessous\\ +\verb-{>3}- & copie vers les 3 cellules de droite\\ +\verb-{v1}- & copie vers la cellule de dessous\\ +\verb-{>}- & copie vers toutes les cellules situées à droite\\ +\verb-{v}- & copie vers toutes les cellules situées en dessous\\ +\verb-{v,>}- & copie vers le bas et vers la droite à partir de la cellule courante\\\hline +\end{tabular} + +On peut facilement générer la table de multiplication de 1 à 10 : + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} +\hline +@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline +1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ +\STcopy{v}{a2+1} & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} +\hline +@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline +1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ +\STcopy{v}{a2+1} & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\ + & & & & & & & & & & \\\hline +\end{spreadtab} +\end{center} + +Lors d'une copie de formule, si la cellule cible contient déjà un champ numérique non vide, celui-ci n'est pas écrasé et la copie ne se fait pas. + +Si des commandes \verbinline-\STcopy- se trouvant danns des plusieurs cellules départ ont une même cellule cible, la formule que cette dernière reçoit est celle correspondant à la dernière commande \verbinline-\STcopy- rencontrée lorsque le tableau est lu de haut en bas et de droite à gauche. Dans l'exemple visuel ci-dessous, le \verbinline-\STcopy- se trouvant dans la cellule rose \falseverb{B1} a son champ cible partiellement recouvert par celui du \verbinline-\STcopy- se trouvant dans la cellule verte \falseverb{C3}. En effet, cette dernière est rencontrée plus tard lors de la lecture du tableau : +\begin{center} +\begin{OOocalc}[2.3cm]{6} +1 &\CC{palepink}\ttfamily\textbackslash STcopy \{v,>\}\{!a1+1\} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} \\ +2 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} ~\par~ \\ +3 &\CC{lightpink} &\CC{palegreen}\ttfamily\textbackslash STcopy \{>2,v1\}\{!a3*10\}&\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink} \\ +4 &\CC{lightpink} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink}~\par~ \\ +5 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink}~\par~ \\ +\end{OOocalc} +\end{center} +Voici cet exemple repris ci-dessous pour mettre en évidence ces comportements. Dans cet exemple, la celule \verb-b5- qui est composée d'un champ numérique et la cellule \verb-c5- qui est mixte, leur champ numérique n'étant pas vide, il est conservé. +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 &\STcopy{v,>}{!a1+1} & & & & \\\hline +2 & & & & & \\\hline +3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline +4 & & & & & \\\hline +5 & -1 & a:={0}b & & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 &\STcopy{v,>}{!a1+1} & & & & \\\hline +2 & & & & & \\\hline +3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline +4 & & & & & \\\hline +5 & -1 & a:={0}b & & & \\\hline +\end{spreadtab} +\end{center} +Comme on l'a dit à la fin du chapitre précédent, on peut également copier une formule dans une cellule de texte contenant un champ numérique vide (c'est-à-dire une cellule contenant \og\verb-:={}-\fg). Dans ce cas, la formule est copiée à l'endroit où se trouve \og\verb-:={}-\fg. Par contre, dans une cellule de texte contenant \og\verb-@-\fg, la copie ne se fait pas et la cellule reste purement textuelle. + +Exemple : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 & 2 & 3 & 4 & 5 & 6 \\\hline +X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*6{c|}}}\hline +1 & 2 & 3 & 4 & 5 & 6 \\\hline +X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline +\end{spreadtab} +\end{center} + +\section{Mise en forme du tableau} +\subsection{Séparateur décimal} +Le package \verb-fp- renvoie ses résultats décimaux avec le point comme séparateur décimal. Il est possible de changer ce séparateur décimal de telle sorte que tout se passe comme si les résultats retournés par \verb-fp- en tenaient compte. L'instruction \verbinline-\STsetdecimalsep- permet de changer le séparateur décimal en n'importe quel caractère en utilisant la syntaxe : +\begin{center} +\verbinline-\STsetdecimalsep-\verb-{}- +\end{center} +Pour une utilisation en langue française, il faut donc inclure dans le préambule cette ligne : +\begin{center} +\verbinline-\STsetdecimalsep{,}- +\end{center} +Pour les champs numériques se trouvant en mode math, il faut noter que la virgule n'est pas neutre dans ce mode. En effet, elle est considérée comme une ponctuation ce qui explique qu'elle est suivie d'une espace. Pour neutraliser cet espace, on peut mettre cette virgule entre accolades comme on le voit dans ce code : + +\begin{minipage}{0.65\linewidth} +\begin{lstlisting}[escapechar=Z,backgroundcolor=\color{ST@codebckgcolor}] +3,14 n'est pas affichZéZ comme $3,14$.\par +3,14 est affichZéZ comme $3{,}14$ +\end{lstlisting} +\end{minipage}\hfill +\begin{minipage}{0.35\linewidth} +3,14 n'est pas affiché comme $3,14$.\par +3,14 est affiché comme $3{,}14$ +\end{minipage}% + +Lorsque des cellules sont en mode math, on peut\footnote{Il est cependant préférable d'utiliser le package \texttt{numprint} pour formatter les résultats. On peut aussi modifier le code mathématique de la virgule : \texttt{\textbackslash mathcode`,="013B\textbackslash relax}. Cette modification, réservée aux utilisateurs avertis, fait entrer la virgule dans la classe 0 des signes ordinaires alors qu'elle est naturellement dans la classe 6 des signes de ponctuation.} s'inspirer de cette propriété et demander à \ST de remplacer le point décimal par une virgule entre accolades avec la commande \verbinline-\STsetdecimalsep{{,}}-. Dans ces deux tableaux où chaque cellule est en mode math, on constate que l'espacement après la virgule est neutralisé pour le second : + +\begin{minipage}{0.65\linewidth} +\begin{lstlisting} +\STsetdecimalsep{,} +\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline +@x & @y & @\text{Moyenne}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab}\par\smallskip +\STsetdecimalsep{{,}} +\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline +@x & @y & @\text{Moyenne}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.35\linewidth} +\centering +\STsetdecimalsep{,} +\begin{spreadtab}{{tabular}{|*3{>$r<$}|}}\hline +@x & @y & @\text{Moyenne}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab}\par\smallskip +\STsetdecimalsep{{,}} +\begin{spreadtab}{{tabular}{|*3{>$r<$}|}}\hline +@x & @y & @\text{Moyenne}\\\hline +5 & -4 & (a2+b2)/2\\ +-6.1 & -8 & (a3+b3)/2\\ +9.85 & 3.7 & (a4+b4)/2\\\hline +\end{spreadtab} +\end{minipage} + +\subsection{Mise en forme des nombres} +Comme cela a été précisé, tous les calculs sont faits par le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} et sa macro \falseverb{\FPeval}\footnote{À ce propos, les notations infixe ou postfixe sont acceptées par {\ttfamily\string\FPeval} ce qui signifie que les formules dans \ST peuvent être indifféremment sous forme infixe ou postfixe. Par exemple, la formule infixe \og\falseverb{a1+b1}\fg{} est équivalente aux formules postfixes \og\falseverb{a1 b1 add}\fg{} ou \og\falseverb{a1 b1 +}\fg.}. Ce package fournit d'extraordinaires possibilités de calcul pour \TeX{} et dispose de toutes les fonctions arithmétiques, scientifiques et trigonométriques usuelles. Les calculs sont faits avec une précision de $10^{-18}$, et les 18 décimales sont affichées lorsqu'un calcul ne tombe pas juste ! Sans prendre des précautions, on peut se retrouver avec beaucoup de chiffres dans les parties décimales de certains résultats. + +Pour se prémunir de ce problème, plusieurs solutions existent : +\begin{itemize} + \item on peut utiliser le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/numprint/}{\texttt{\textbf{numprint}}} qui est ce qui se fait de mieux dans l'affichage des nombres; + \item on peut demander à \verb=fp= d'arrondir un résultat avec sa fonction \verb-round(nombre,entier)- qui arrondit \verb=nombre= avec \verb=entier= chiffres après la virgule; + \item on peut également demander à \ST d'arrondir \emph{tous} les nombres placés dans le tableau à une certaine précision avec la macro \verbinline-\STautoround- dont l'argument est le nombre de chiffres demandés après la virgule. Si l'argument est vide, aucun arrondi n'est fait. Si on utilise la macro étoilée \verbinline-\STautoround*-, la partie décimale est remplie si besoin avec des 0 inutiles. +\end{itemize} +Voici un exemple simple des nombres de 1 à 7 et leurs inverses, arrondis à $10^{-6}$ :\par\nobreak +\begin{lstlisting} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab}\medskip + +\STautoround*{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab}\medskip + +\STautoround*{6} +\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} +\hline +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline +@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline +\end{spreadtab} +\end{center} + +Tous les nombres contenus dans le tableau final, qu'ils aient été saisis tels quels ou qu'ils proviennent du résultat d'un calcul sont traités par la macro \verbinline-\STprintnum-. Par défaut, cette macro n'a aucun effet et est programmée de la façon suivante : +\begin{center} + \verbinline-\newcommand\STprintnum[1]{#1}- +\end{center} +Il est possible d'arrondir tous les nombres via la commande \verbinline-\numprint- du package \verb-\numprint-. Pour ce faire, il faut redéfinir la macro \verbinline-\STprintnum- de cette façon :\par\nobreak +\begin{lstlisting} +\renewcommand\STprintnum[1]{\numprint{#1}} +\nprounddigits{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\renewcommand\STprintnum[1]{\numprint{#1}} +\nprounddigits{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{center} + +Voici un autre exemple similaire où l'on teste si le nombre à afficher est négatif avec la commande \verbinline-\FPifneg- du package \verb-fp-. Si tel est le cas, le nombre est affiché en rouge. La commande \verbinline-\STautoround- a été préférée à \verbinline-\nprounddigits- du package \verb-numprint- puisque cette dernière ajoute des 0 inutiles. On a également remis le point décimal par défaut puisque \verbinline-\numprint- est en charge de l'affichage des nombres. +\begin{lstlisting} +\STsetdecimalsep{.} +\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} +\STautoround{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STsetdecimalsep{.} +\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} +\STautoround{6} +\begin{spreadtab}{{tabular}{cccccccc}} +@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline +@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 +\end{spreadtab} +\end{center} + +\subsection{Retours à la ligne et filets horizontaux} +Pour bien délimiter la fin d'une ligne, \ST est contraint de reconnaître les retours à la ligne et les filets horizontaux. Ce package permet d'utiliser dans le tableau l'argument optionnel de \verb-\\- de cette façon : \verb-\\[]-. + +Pour les filets horizontaux, on peut utiliser autant de fois que l'on veut: +\begin{itemize} + \item \verb-\hline-; + \item \verb=\cline{x-y}= où \falseverb x et \falseverb y sont les numéro des colonnes de départ et d'arrivée du filet; + \item \verb=\hhline{}= où \verb== est le type de ligne désirée (voir la documentation du package \href{http://www.ctan.org/tex-archive/macros/latex/required/tools/}{\texttt{\textbf{hhline}}}). + \item n'importe quelle commande du package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/booktabs/}{\texttt{\textbf{booktabs}}}, à savoir \verb-\toprule-, \verb-\midrule-, \verb-\bottomrule-, \verb-\cmidrule-, \verb-\addlinespace-, \verb-\morecmidrule- et \verb-\specialrule-. Tous les arguments de ces macros, optionnels ou pas sont gérés; + \item \verbinline-\noalign- et son argument peuvent être placés après \verb-\\- et pris en compte. +\end{itemize} +Voici le triangle de Pascal inversé, et massacré pour l'exemple :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*5c}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline +[0,1] & [-1,1] & & & \\ \cline{2-4} +1 & & & & \\ \hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{*5c}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline +[0,1] & [-1,1] & & & \\ \cline{2-4} +1 & & & & \\ \hline +\end{spreadtab} +\end{center} + +\subsection{Masquer une ligne ou une colonne} +Parfois, une colonne ou une ligne entière est destinée à recevoir des calculs intermédiaires qui n'ont pas à être affichés dans le tableau final. Pour cela \ST dispose de deux séquences de contrôle \verbinline=\SThiderow= et \verbinline=\SThidecol= qui, lorsqu'elles sont placées dans une cellule, masquent la ligne ou la colonne dans laquelle se trouve cette cellule. + +Voici un exemple :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ valeurs de $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline +@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ +@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ +@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|ccc|}} +\hline +@ valeurs de $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline +@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ +@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ +@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline +\end{spreadtab} +\end{center} +On peut observer comment on masque la ligne contenant $g(x)$ et la colonne correspondant à la valeur 0. + +Il faut se souvenir que les lignes et les colonnes masquées sont \emph{invisibles} pour l'environnement tableau choisi par l'utilisateur, ce qui explique que dans le préambule du tableau, seules 4 colonnes (\falseverb{|r|ccc|}) aient été définies et non 5 comme le voit \ST. + +Pour voir la différence, voici le tableau obtenu en définissant 5 colonnes et en ne masquant aucune ligne ni colonne :\par\nobreak +\begin{center} +\begin{spreadtab}{{tabular}{|r|cccc|}} +\hline +@ valeurs de $x$ & -1 & 0 & 2 & 3 \\\hline +@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ +@$g(x)=x-10$ & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ +@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline +\end{spreadtab} +\end{center} + +\subsection{Sauvegarder la valeur d'une cellule} +On peut être amené à avoir besoin de la valeur numérique d'une cellule dans le tableau pour l'afficher en dehors d'une formule ou même à l'extérieur du tableau. On doit alors utiliser la commande :\par\nobreak +\begin{center} +\verbinline-\STsavecell{}{}- +\end{center} +Avec un \verbinline-\global\def-\footnote{La commande \texttt{\string\def} ne vérifie pas si la macro qu'elle définit existe déjà.}, cette commande a pour effet de sauvegarder de façon globale dans \falseverb{} le résultat de la formule contenue dans la cellule \falseverb{}. + +On ne peut utiliser que des références \emph{absolues}; les références relatives ne sont pas acceptées car cette commande doit se placer dans l'argument optionnel de l'environnement \verbinline-spreadtab-. + +Exemple :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} +\hline +10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline +\end{spreadtab} +\par\medskip +Voici la cellule c1 : \result +\end{lstlisting} +\begin{center} +\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} +\hline +10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline +\end{spreadtab} +\par\medskip +Voici la cellule c1 : \result +\end{center} +Si l'on veut sauvegarder plusieurs cellules, on peut mettre autant de fois que l'on veut la commande \verbinline-\STsavecell- dans l'argument optionnel. + +Exemple :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline +@Vitesse (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ +@distance (km) & & & & 180\\\hline +@Temps (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline +\end{spreadtab}\par\medskip +On met au moins \hhh\ heures +\end{lstlisting} +\begin{center} +\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline +@Vitesse (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ +@distance (km) & & & & 180\\\hline +@Temps (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline +\end{spreadtab}\par\medskip +On met au moins \hhh\ heures +\end{center} + +\subsection{Afficher la valeur d'une cellule} +Pour afficher la valeur du champ numérique d'une cellule dans le champ textuel, on vient de voir qu'on pouvait sauvegarder cette valeur dans une séquence de contrôle et se servir de cette séquence de contrôle pour l'afficher ensuite. Le procédé est un peu fastidieux et détourne de ses intentions la commande \verbinline-\STsavecell- qui sert surtout à sauvegarder une valeur pour l'utiliser en dehors du tableau. + +Pour afficher simplement la valeur du champ numérique d'une cellule dans un champ textuel, on peut utiliser la syntaxe \verb-<>- qui sera remplacé par la valeur numérique de la cellule \verb-référence- où la \verb-référence- peut être relativess ou absolue. Si ce qui est entre \verb-<<- et \verb->>- n'est pas une référence, alors rien n'est fait et \verb-<>- est laissé en l'état. La \verb-référence- ne doit contenir aucun espace. Si on écrit \verb-<< a1>>- alors, l'espace fait que la référence n'est pas reconnue et rien ne sera fait. + +Exemple dans une cellule purement textuelle \verb-a3- : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{lr}} +@Prix de vente & 250 \\ +@Prix d'achat & 216 \\\hline +@B\'en\'efice (<>-<>) & b1-b2 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{lr}} +@Prix de vente & 250 \\ +@Prix d'achat & 216 \\\hline +@B\'en\'efice (<>-<>) & b1-b2 +\end{spreadtab} +\end{center} +Exemple dans la cellule mixte c1 : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +23 & 32 & Moyenne $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|c|c||c|}}\hline +23 & 32 & Moyenne $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline +\end{spreadtab} +\end{center} +Les caractères qui délimitent la référence valent "\verb-<<-" et "\verb->>-" par défaut. Ils peuvent être modifiés avec la commande \verbinline-\STsetdisplaymarks- dont les 2 arguments définissent le délimiteur de gauche et le délimiteur de droite. En écrivant \verbinline-\STsetdisplaymarks{|}{|}-, on devra écrire \verb-|référence|- pour provoquer l'affichage du champ numérique de la cellule \verb-référence-. + +\subsection{Utiliser \ttfamily\textbackslash multicolumn} +Le package \ST est compatible avec la syntaxe \verbinline=\multicolumn{}{}{}= qui fusionne \falseverb{} cellules en une cellule de type et de contenu spécifiés dans les arguments. + +En utilisant \verbinline=\multicolumn=, \ST permet même de conserver une certaine cohérence au niveau du référencement des cellules. Sur ce tableau où des cellules sont fusionnées, les cases du tableau contiennent les références absolues vues par \ST :\par\nobreak +\begin{center} +\ttfamily +\begin{tabular}{|*7{c|}}\hline +a1&b1&c1&d1&e1&f1&g1\\\hline +a2&\multicolumn{2}{l|}{b2}&d2&e2&f2&g2\\\hline +\multicolumn{3}{|l|}{a3}&d3&\multicolumn{2}{l|}{e3}&g3\\\hline +\end{tabular} +\end{center} +Ainsi, quelque soit le nombre de cellules fusionnées, la cellule suivante porte un numéro de colonne qui tient compte du nombre de cellules fusionnées. + +Sur la dernière ligne, les cellules \falseverb{a3}, \falseverb{b3} et \falseverb{c3} sont fusionnées, et si la cellule \falseverb{a3 }contient une formule, les cellules \falseverb{b3} et \falseverb{c3} \emph{n'existent pas} pour \ST : on ne peut nulle part faire référence à ces cellules. + +Voici un exemple où chaque nombre de la ligne du haut est le produit des 2 nombres se trouvant au dessous de lui :\par\nobreak +\begin{lstlisting} +\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} +\begin{spreadtab}{{tabular}{*6{K{0.5}}}} +\cline{2-5} +&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline +\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} +\begin{spreadtab}{{tabular}{*6{K{0.5}}}} +\cline{2-5} +&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline +\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline +\end{spreadtab} +\end{center} +On remarque que le marqueur de champ numérique \og\falseverb{:=}\fg{} est nécessaire dans chaque cellule où se trouve la commande \verbinline-\multicolumn-. On comprend en effet que si ce marqueur n'existait pas, la totalite de la cellule, c'est-à-dire \verb-\multicolumn{2}{|c|}{}- serait considérée comme étant une formule. + +\section{Macro-fonctions} +L'extension \falseverb{fp} fournit un nombre conséquent d'opérations et de fonctions. Malgré tout, dans le cadre d'un package comme \ST, celles-ci peuvent être insuffisantes et il est possible au programmeur averti d'écrire des macro-fonctions supplémentaires en utilisant celles fournies par \falseverb{fp}. Cette section présente les macro-fonctions pour l'instant disponibles\footnote{Bien d'autres restent à écrire ! Elles seront disponibles dans des versions futures de \ST.}. Il y aura plus de précisions sur la méthode pour programmer des macro-fonctions dans la prochaine version de ce manuel. + +\subsection{Macro-fonctions mathématiques} +\subsubsection{Sommer des cellules} +La fonction \og\verbinline=sum=\fg permet de faire la somme d'une ou plusieurs plages de cellules. + +Elle s'utilise ainsi : \verbinline=sum(;;...;)=, où une plage de cellules est : +\begin{itemize} + \item soit une cellule isolée comme \og\falseverb{a1}\fg{} ou \og\falseverb{[2,1]}\fg{}; + \item soit une zone rectangulaire délimitée par la cellule supérieure gauche et inférieure droite de cette façon : \og\verb=:=\fg, à condition que \og\verb==\fg se trouve \emph{avant} \og\verb==\fg{} lorsqu'on parcourt le tableau de haut en bas, de gauche à droite.\par + Voici des exemple de plages de cellules : \og\falseverb{a2:d5}\fg{}, \og\falseverb{[-1,-1]:[2,3]}\fg{}, \og\falseverb{b4:[5,1]}\fg{}. +\end{itemize} +Dans les plages de cellules, les cellules vides ou ne contenant que du texte sont considérées comme contenant le nombre 0. Il en est de même pour les cellules masquée car fusionnées par \verbinline-\multicolumn-. + +Les références relatives et absolues peuvent être utilisées conjointement, comme il semble bon à l'utilisateur. Voici un exemple où l'on fait la somme des coefficients du triangle de Pascal :\par\nobreak +\begin{minipage}{0.75\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*5c}} +\multicolumn{5}{c}{somme=:={sum(a2:e6)}}\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1] & & & \\ +1 & & & & +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.25\linewidth} +\centering +\begin{spreadtab}{{tabular}{*5c}} +\multicolumn{5}{c}{somme=:={sum(a2:e6)}}\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1] & & & \\ +1 & & & & +\end{spreadtab} +\end{minipage}% + +\subsubsection{Macro-fonction \ttfamily fact} +La macro-fonction \verbinline=fact()= permet de calculer la factorielle de son argument, sous réserve que celui-ci soit un entier compris entre 0 et 18 inclus pour éviter des débordements\footnote{En effet, pour \falseverb{fp} le plus grand entier est $10^{18}-1$. La factorielle de 19 dépasse ce nombre.}. Le \falseverb{} peut aussi être une référence vers une cellule contenant un nombre entier. + +Voici les factorielles de 0 à 8 :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*9c}} + 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline +fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{*9c}} + 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline +fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) +\end{spreadtab} +\end{center} + +\subsubsection{Macro-fonction \ttfamily sumprod} +La fonction \verbinline=sumprod= permet de multiplier les éléments correspondants de 2 plages ou plus et ensuite, additionner ces produits. + +Cette fonction s'utilise ainsi : \verbinline{sumprod(;;...;)}. Toutes les plages rectangulaires doivent avoir les mêmes dimensions. + +Voici un exemple simple où l'on calcule l'âge moyen d'un groupe d'enfants âgés de 10 à 15 ans :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{r*6c}} +@\^Ages & 10 & 11 & 12 & 13 & 14 & 15\\ +@Nombre & 5 & 8 & 20 & 55 & 9 & 3\\\hline +@Moyenne&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{r*6c}} +@\^Ages & 10 & 11 & 12 & 13 & 14 & 15\\ +@Nombre & 5 & 8 & 20 & 55 & 9 & 3\\\hline +@Moyenne&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} +\end{spreadtab} +\end{center} +De la même façon que pour la macro-fonction \verbinline-sum-, les cellules de texte, vides ou fusionnées par un \verbinline-\multicolumn- sont considérées comme contenant le nombre 0. + +\subsubsection{Nombres aléatoires} +Les macro-fonctions \verbinline-randint- et \verbinline-rand- renvoient un nombre aléatoire. + +À noter : la \og graine\fg{} qui initialise la suite aléatoire dépend de la date ainsi que de la la minute à laquelle est faite la compilation. Les séries aléatoires données par cette fonction changeront entre deux compilations faites à des heures dont les minutes diffèrent. Si l'on veut vraiment avoir des nombres aléatoires indépendant du moment de compilation et donc reproductibles, il faut neutraliser la macro interne \verb-\ST@seed- et définir une graine pour \verb-fp- :\par\nobreak +\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] +\makeatletter +\renewcommand\ST@seed{}% redefinit la macro interne +\makeatother +\FPseed=27% donne une graine (n'importe quel entier) a fp +\end{lstlisting} +La macro fonction \verbinline-randint([,])- renvoie une nombre \emph{entier} qui dépend des paramètres : \verb== est un entier optionnel qui vaut 0 par défaut. L'entier aléatoire renvoyé est compris dans l'intervalle \verb=[;]=. + +La macro fonction \verbinline-rand()- renvoie un nombre aléatoire décimal compris entre 0 et 1 :\par\nobreak +\begin{lstlisting} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|cccc|}}\hline +@nombres dans [0;1] &rand() &rand() &rand() &rand() \\ +@nombres dans [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ +@nombres dans [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ +\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STautoround{6} +\begin{spreadtab}{{tabular}{|l|cccc|}}\hline +@nombres dans [0;1] &rand() &rand() &rand() &rand() \\ +@nombres dans [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ +@nombres dans [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ +\hline +\end{spreadtab} +\end{center} + +\subsubsection{PGCD et PPCM} +Les macros fonctions "gcd" et "lcm" permettent de calculer le Plus Grand Commun Diviseur (PGCD) et le Plus Petit Commun Multiple (PPCM) des nombres passés en arguments et séparés par des virgules : +\begin{center} +\verbinline-gcd(nombre1,nombre2,...,nombreN)-\par +\verbinline-lcm(nombre1,nombre2,...,nombreN)- +\end{center} +Exemple : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline +\multicolumn3{|c||}{@Nombres}& @PGCD & @PPCM \\\hline +24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ +15 & 10 & 25 & & \\ +16 & 12 & 15 & & \\ +\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline +\multicolumn3{|c||}{@Nombres}& @PGCD & @PPCM \\\hline +24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ +15 & 10 & 25 & & \\ +16 & 12 & 15 & & \\ +\hline +\end{spreadtab} +\end{center} + +\subsubsection{Écriture scientifique} +La macro fonction "scitodec" permet de convertir un nombre écrit en écriture scientifique en nombre décimal compréhensible par \ST pour faire ses calculs. La syntaxe est \verbinline-scitodec()-, où le \verb-- est : +\begin{enumerate}[label=--] + \item une suite de caractères se présentant sous la syntaxe \verb-EE-, où la \verb-- est un nombre décimal et l'\verb->exposant>- est un entier relatif. Les "E" peuvent être écrit en majuscule ou minuscule. + + Le nombre ainsi représenté est $\text{\ttfamily }\times10^{\text{\ttfamily }}$ + \item une référence au champ \emph{textuel} d'une cellule qui doit contenir des caractères obéissants à la syntaxe vue au point précédent. +\end{enumerate} +Exemple : +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|r|}}\hline +@Écritures scientifiques & @Écritures décimales \\\hline +@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ +@-3.1EE-3 & \\ +@15ee5 & \\ +@-0.025ee7 & \\ +@2.125EE0 & \\ +@3.1575EE-4 & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|r|}}\hline +@Écritures scientifiques & @Écritures décimales \\\hline +@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ +@-3.1EE-3 & \\ +@15ee5 & \\ +@-0.025ee7 & \\ +@2.125EE0 & \\ +@3.1575EE-4 & \\\hline +\end{spreadtab} +\end{center} + +\subsubsection{Identité} +La plus simple des macros fonctions est \og\verbinline=id()=\fg. Celle-ci renvoie le nombre qui se trouve entre parenthèses. Mathématiquement, elle ne sert pas à grand chose, mais avec \ST, elle permet de passer des expressions mathématiques à des macros qui n'en admettent pas. On peut ainsi s'en servir dans les plages de cellules de \verbinline=sum= par exemple. + +Dans le code ci dessous, la macro \verbinline=id= est utilisée pour déterminer la plage de cellules à additionner avec \verbinline-sum-. Dans cet exemple, la valeur du champ numérique de la cellule a2 vaut 8. Et donc, "\verbinline=sum([0,-1]:[id(a2-1),-1])/a2=" est équivalent à \verbinline=sum([0,-1]:[7,-1])/8= : + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{r*{10}c}} + @Entiers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ +Moyenne des :={8} premiers entiers & sum([0,-1]:[id(a2-1),-1])/a2 \\ +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{r*{10}c}} + @Entiers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ +Moyenne des :={8} premiers entiers & sum([0,-1]:[id(a2-1),-1])/a2 \\ +\end{spreadtab} +\end{center} + +\subsection{Macro-fonctions de test} +Elles sont au nombre de 3 et ont la syntaxe suivante :\par\nobreak +\begin{center} +\verbinline=ifeq(nombre1,nombre2,nombre3,nombre4)=\par +\verbinline=ifgt(nombre1,nombre2,nombre3,nombre4=\par +\verbinline=iflt(nombre1,nombre2,nombre3,nombre4)= +\end{center} +La comparaison se fait entre \falseverb{nombre1} et \falseverb{nombre2} : +\begin{itemize} + \item test d'égalité pour \verbinline-ifeq- : \falseverb{nombre1} = \falseverb{nombre2} ? + \item test de supériorité stricte pour \verbinline-ifgt- : \falseverb{nombre1} > \falseverb{nombre2} ? + \item test d'infériorité stricte pour \verbinline-iflt- : \falseverb{nombre1} < \falseverb{nombre2} ? +\end{itemize} +Si le test est vrai, \falseverb{nombre3} est retourné, sinon c'est \falseverb{nombre4}. + +À titre d'exemple, voici quelques valeurs de la fonction +$f(x)=\begin{cases} +10 &\text{si }x<1\\ +0 &\text{si }x=1\\ +-10 &\text{si }x>1 +\end{cases} +$\smallskip + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*2c|}}\hline +@$x$ & @$f(x)$ \\\hline +-0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*2c|}}\hline +@$x$ & @$f(x)$ \\\hline +-0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ +[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline +\end{spreadtab} +\end{center} + +\subsection{Macro-fonctions de date} +\subsubsection{Convertir une date en nombre avec \ttfamily frshortdatetonum}\label{datetonum} +La macro \verbinline-frshortdatetonum- permet de convertir une date de la forme 14/7/1789 en un nombre qui est en fait le nombre de jours écoulés depuis le 1\ier{} mars de l'an 0\footnote{Cet \og an 0\fg{} n'existe d'ailleurs pas, mais cela ne devrait pas être gênant pour les dates contemporaines}. Il est important de noter que cette macro-fonction requiert un argument \emph{textuel} et non pas un nombre ou le résultat d'un calcul mathématique. Par conséquent, si l'argument de cette macro-fonction fait référence à une cellule, cette cellule \emph{doit} être une cellule textuelle, c'est à dire contenant \og\verb-@-\fg{} ou \og\verb-:={}-\fg{} + +Dans l'exemple ci-dessous, les deux premières lignes montrent que la cellule de gauche contient une date, et la cellule de droite fait référence à cette date pour calculer le nombre correspondant. La troisième ligne montre dans la cellule de gauche la date 0, mais surtout calcule dans la cellule de droite le nombre correspondant à la date \emph{d'aujourd'hui}, en transformant en nombre les compteurs de \TeX{} \verbinline-\day-, \verbinline-\month- et \verbinline-\year- qui contiennent les numéros des jours, mois et année courants.\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} +@14/7/1789 & frshortdatetonum(a1)\\ +1/1/2001 :={} & frshortdatetonum(a2)\\\hline +frshortdatetonum(1/3/0) & frshortdatetonum(\number\day/\number\month/\number\year) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{cc}} +@14/7/1789 & frshortdatetonum(a1)\\ +1/1/2001 :={} & frshortdatetonum(a2)\\\hline +frshortdatetonum(1/3/0) & frshortdatetonum(\number\day/\number\month/\number\year) +\end{spreadtab} +\end{center} +Une autre macro-fonction existe, elle transforme une date longue du type \og 25 décembre 1789\fg{} en un nombre. L'argument peut aussi être la séquence de contrôle \verbinline-\today- si l'on a pris le soin de charger l'extension \verb-babel- avec l'option \verb-frenchb-.\par\nobreak +\begin{lstlisting}[escapechar=Z] +\begin{spreadtab}{{tabular}{cc}} +frlongdatetonum(\today) & frlongdatetonum(25 dZéZcembre 2009)\\ +@1 juillet 1970 & frlongdatetonum(a2) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{cc}} +frlongdatetonum(\today) & frlongdatetonum(25 décembre 2009)\\ +@1 juillet 1970 & frlongdatetonum(a2) +\end{spreadtab} +\end{center} + +\subsubsection{Passer d'un nombre à une date} +Plusieurs macro-fonctions permettent de traduire un nombre en une donnée de date. Toutes ces macro-fonctions ont en commun que leur résultat est du \emph{texte}. Par conséquent, \emph{la cellule les contenant deviendra une cellule textuelle} dont le texte sera le résultat de cette fonction. Si un texte cohabitait avec la formule dans cette cellule, le résultat de la formule sera inséré à la place de \verb-:={}-. Il en résulte que la cellule ne peut plus faire l'objet d'aucun traitement mathématique ensuite. + +Voici ces fonctions : +\begin{itemize} + \item \verbinline-numtofrshortdate- transforme un nombre en une date courte du type 14/7/1789; + \item \verbinline-numtofrlongdate- transforme un nombre en une date longue du type \og 14 juillet 1789\fg; + \item \verbinline-numtofrmonth- extrait d'un nombre représentant une date le nom du mois correspondant; + \item \verbinline-numtofrday- extrait d'un nombre représentant une date le nom du jour correspondant. +\end{itemize} +Voici un exemple où l'on se place 1000 jours avant puis 1000 jours après le 1/6/2009. Pour chacune de ces 2 dates, on calcule la date courte, la date longue, le mois et le jour de la semaine.\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} \hline +\multicolumn{2}{|c|}{@1/6/2009} \\\hline\hline +1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ +1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ +1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ +1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) \\\hline +-1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ +-1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{cc}} \hline +\multicolumn{2}{|c|}{@1/6/2009} \\\hline\hline +1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ +1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ +1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ +1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) \\\hline +-1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ +-1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ +-1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) +\end{spreadtab} +\end{center} + +\subsection{Macro fonctions de coordonnées}\label{tag} +Plutôt que de faire référence à une cellule par ses coordonnées qui sont difficiles à mémoriser et qui changent si on insère une ligne ou une colonne, il est parfois bien plus pratique de donner un nom à une cellule et d'y faire référence plus loin par ce nom. + +La macro fonction ``\verbinline-tag()-'' a pour effet de nommer la cellule dans laquelle elle se trouve. Il ne s'agit pas vraiment d'une macro fonction comme les autres puisque ce qu'elle retourne rien lorsqu'elle est mise dans une formule : elle disparait sans provoquer aucun effet sur le résultat mathématique. On peut donc écrire ``\verbinline-tag()-'' \emph{n'importe où} dans le champ numérique d'une cellule. Le \verb-- peut être n'importe quelle suite de caractères alphanumériques, mais il est déconseillé de mettre une lettre et un nombre, qui pourraient être compris comme une référence à une cellule, et serait donc modifié lors d'une opération de copie avec \verbinline-\STcopy-. Cette macro fonction a une action supplémentaire, elle sauvegarde via un \verbinline-\def- la valeur numérique de la cellule dans laquelle elle se trouve de façon à pouvoir y faire appel plus tard \emph{en dehors du tableau} via la commande purement développable \verbinline-\STtag{}-. + +Par la suite dans le tableau, au lieu de mettre les coordonnées de la cellule \verb--, on peut écrire ``\verbinline-cell()-'' qui est une macro fonction qui renvoit les coordonnées de la cellule précédemment nommée. Par exemple si ``\verbinline-tag()-'' a été écrit dans la cellule ``\verb-B3-'' si on a écrit plus loin ``cell()'', cette macro fonction renvoit \verb-B3-. + +Voici un exemple où l'on fait la somme de cellules et l'on donne le nom ``\verb-foo-'' au premier nombre et le nom ``\verb-bar-'' au dernier. On peut observer que \verbinline-tag(bar)- se trouve entre ``1'' et ``9'' et qu'au final, puisque cette macro fonction disparait, le champ numérique de la cellule contiendra ``19'' : + +\begin{minipage}{0.6\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{r@{}r}} + & 15tag(foo) \\ +@+ & 37 \\ +@+ & 13 \\ +@+ & 48 \\ +@+ & 1tag(bar)9 \\\cline{2-2} + & sum(cell(foo):cell(bar))tag(baz) +\end{spreadtab} + +foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} +\end{lstlisting} +\end{minipage}\kern6pt% +\begin{minipage}{0.3\linewidth} +\begin{spreadtab}{{tabular}{r@{}r}} + & 15tag(foo) \\ +@+ & 37 \\ +@+ & 13 \\ +@+ & 48 \\ +@+ & 1tag(bar)9 \\\cline{2-2} + & sum(cell(foo):cell(bar))tag(baz) +\end{spreadtab} + +foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} +\end{minipage} + +Pour transmettre des valeurs entre tableaux calculés par \ST\footnote{Comme on l'avait demandé sur \href{https://tex.stackexchange.com/questions/210881}{\texttt{\textbf{tex.stackexchange}}}}, il est possible de taguer la cellule dans le premier tableau à l'aide de la macro fonction \verbinline|tag()|, puis dans le 2\ieme{} tableau, de faire appel à la valeur \emph{via} tagguée par \verbinline|valtag()| + +\begin{minipage}{.6\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{cc}} + 100 & a1+1tag{abcd} +\end{spreadtab} + +\begin{spreadtab}{{tabular}{c}} + value{abcd} +\end{spreadtab} +\end{lstlisting} +\end{minipage}\kern6pt +\begin{minipage}{.3\linewidth} +\begin{spreadtab}{{tabular}{cc}} + 100 & a1+1tag(abcd) +\end{spreadtab} + +\begin{spreadtab}{{tabular}{c}} + value(abcd) +\end{spreadtab} +\end{minipage} + +Lorsque l'environnement \ST se trouve inclus dans un autre environnement, les affectations faites par la macro fonction \verb-tag- restent \emph{locales} à cet environnement et ne pourraient pas être accessibles en dehors de cet environnement via \verbinline-\STtag-. Dans l'exemple ci-dessous, le tableau fait par \ST est dans un environnement \verb-center- et l'on doit donc utiliser \verbinline-\STmakegtag{}- pour rendre global la sauvegarde de la valeur numérique contenus dans la cellule marquée par ``tag{}'' : + +\begin{minipage}{.6\linewidth} +\begin{lstlisting} +\begin{center} + \begin{spreadtab}{{tabular}{cccc}}\hline + 6&9&17&21\\\hline + \multicolumn{4}{c}{moyenne = :={sum(a1:d1)/4tag(moy)}} + \end{spreadtab} + \STmakegtag{moy} +\end{center} +La moyenne est de \STtag{moy}. +\end{lstlisting} +\end{minipage}\kern6pt +\begin{minipage}{.3\linewidth} +\begin{center} + \begin{spreadtab}{{tabular}{cccc}}\hline + 6&9&17&21\\\hline + \multicolumn{4}{c}{moyenne = :={sum(a1:d1)/4tag(moy)}} + \end{spreadtab} + \STmakegtag{moy} +\end{center} +La moyenne est de \STtag{moy}. +\end{minipage} + +L'argument de \verbinline-\STmakegtag- peut êre constitué de plusieurs noms séparés par des virgules. + +Bien qu'elles soient à première vue moins utiles, \ST fournit également les macros fonctions ``\verbinline-row()-'' et ``\verbinline-col()-'' qui renvoient le numéro de la ligne ou de la colonne où se trouvait \verbinline-tag()-. Voici par exemple une façon de dénombrer des valeurs pour en calculer la moyenne : on nomme ``un'' la première valeur et ``der'' la dernière, et le nombre de valeurs est donc row(der)-row(un)+1 : + +\begin{minipage}{0.6\linewidth} +\begin{lstlisting} +moyenne = \begin{spreadtab}{{tabular}[b]{r}} +7tag(un)\\9\\15\\6\\20\\13\\11\\55tag(der)\\ +\hline +sum(cell(un):cell(der))/(row(der)-row(un)+1) +\end{spreadtab} +\end{lstlisting} +\end{minipage}\hfill +\begin{minipage}{0.35\linewidth} +moyenne = \begin{spreadtab}{{tabular}[b]{r}} +7tag(un)\\9\\15\\6\\20\\13\\11\\55tag(der)\\ +\hline +sum(cell(un):cell(der))/(row(der)-row(un)+1) +\end{spreadtab} +\end{minipage} + +\section{Précautions particulières} +\subsection{Redéfinition des commandes de filets horizontaux} +On peut être tenté de définir une commande pour produire ---~par exemple~--- une double ligne horizontale :\par\nobreak +\begin{center} +\verbinline-\newcommand\dline{\hline\hline}- +\end{center} +puis essayer de l'utiliser dans un tableau pour produire ce simple exemple qui calcule à la seconde ligne les termes de la suite de Fibonacci :\par\nobreak +\begin{center} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{center} +Mais en écrivant ce code, il y a un problème :\par\nobreak +\begin{lstlisting} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +1 & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{lstlisting} +En effet la compilation échoue et dans le log, on peut lire que \verb-\FPeval- se plaint :\par +\hfill\falseverb{! Improper alphabetic constant.}\hfill\null + +La raison est simple, c'est que le \verb-\dline- de la ligne 4, n'est \emph{pas} reconnu par \ST comme un filet horizontal et \emph{il se retrouve donc dans la cellule de la ligne suivante}. Pour \ST, cette cellule \falseverb{b1} contient :\par +\hfill\falseverb{\dline 1}\hfill\null + +Comme il n'y a pas de \verb-@- ni de délimiteur de formule \verb-:={...}-, \verb-\FPeval- essaie vaillamment de calculer ce contenu et échoue évidemment ! + +Pour pouvoir compiler ce code sans erreur, la cellule \falseverb{a2} \emph{doit} contenir un marqueur de champ numérique :\par\nobreak +\begin{lstlisting} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{lstlisting} +\begin{center} +\newcommand\dline{\hline\hline} +\begin{spreadtab}{{tabular}{*7c}} +0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline +:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 +\end{spreadtab} +\end{center} + +\subsection{Cohabitation de {\ttfamily\textbackslash multicolumn} et \ttfamily\textbackslash SThidecol} +Tout d'abord, dans une utilisation normale, l'utilisation conjointe de \verbinline|\multicolumn| et \verbinline-\SThiderow- ne doit pas arriver, et la plupart des utilisateurs ne devrait pas rencontrer cette situation ni lire ce chapitre. + +Pour les courageux venons-en au c\oe ur du problème : tout d'abord, une colonne masquée ne doit \emph{jamais} contenir une cellule où se trouve la commande \verbinline-\multicolumn- ! Mais que se passe t-il si une colonne masquée cache des cellules fusionnées par \verbinline-\multicolumn-? + +Déjà, en général, il n'y a pas d'erreur de compilation ni message d'erreur, mais il y a quelques subtilités quant aux références qui sont un peu chamboulées dans la ligne concernée après le \verbinline-\multicolumn-\ldots + +Prenons un exemple, et mettons que dans le tableau suivant, on fusionne les cellules \falseverb{b2} à \falseverb{h2} et que l'on souhaite cacher les colonnes \falseverb{c}, \falseverb{d} et \falseverb{f}, ici en gris :\par\nobreak +\begin{center} +\ttfamily +\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|} +\hline + a1 & b1 & \cellcolor[gray]{0.6}c1 & \cellcolor[gray]{0.6}d1 & e1 & \cellcolor[gray]{0.6}f1 & g1 & h1 & i1 & j1\\\hline + a2 & \multicolumn1c{b2} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1c{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{c}{} & \multicolumn1{c|}{} & i2 & j2\\\hline +\end{tabular} +\end{center} +Il y a 4 cellules \emph{visibles} fusionnées, on écrira donc \verbinline-\multicolumn{4}- car on ne tient \emph{jamais} compte des colonnes masquées dans le décompte du nombre de cellules à fusionner. + +Maintenant, on compte 4 lettres à partir de la lettre \falseverb{b} en l'incluant dans le décompte. On arrive à la lettre \falseverb{e} : cela détermine un intervalle de colonnes \og\falseverb{b-e}\fg. Dans cet intervalle, 2 colonnes masquées sont incluses (\falseverb c et \falseverb d) et 1 colonne masquée n'est pas comprise (\falseverb f). Ces 2 nombres sont importants pour comprendre la suite, aussi, notons-les $x$ et $y$ dans le cas général. + +La règle est la suivante : +\begin{itemize} + \item il faut rajouter $y$ signes \og\verb-&-\fg{} après le \verbinline-\multicolumn- (pour l'exemple, il en faudrait 1). + \item les références des colonnes des cellules qui suivent le \verbinline-\multicolumn- seront décalées de $x$ lettres vers le début de l'alphabet. Pour l'exemple donnée, si on veut faire référence à la cellule marquée \og \falseverb{i2}\fg{}, il faudra écrire \falseverb{g2} (au lieu de \falseverb{i2}). +\end{itemize} +Voici un vrai exemple dont la structure est similaire au précédent : $x=2$ et $y=1$. Dans le code, remarquer le \og\textcolor{red}{\texttt{\&}}\fg{} qui a été ajouté puisque $y=1$. Par ailleurs, on reste simple avec les formules, on ajoute 1 au nombre du dessus :\par\nobreak +\begin{lstlisting}[escapechar=Z] +\begin{spreadtab}{{tabular}{|*{7}{c|}}} +\hline +1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline +a1+1& \multicolumn4{l|}{:={b1+1}}Z\ttfamily\color{red}\rlap\&Z & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*{7}{c|}}} +\hline +1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline +a1+1& \multicolumn4{l|}{:={b1+1}}& & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline +\end{spreadtab} +\end{center} +Voici encore un exemple similaire où une seule colonne est masquée (la colonne \falseverb d), et où $x=1$ et $y=0$ :\par\nobreak +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*{9}{c|}}} +\hline +1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline +a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*{9}{c|}}} +\hline +1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline +a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline +a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline +\end{spreadtab} +\end{center} + +\subsection{Messages émis par \ST} +Le package émet des messages d'erreur et arrête la compilation dans ces cas : +\begin{itemize} + \item Pour calculer une cellule, on calcule de proche en proche des cellules qui par le jeu des références, reviennent sur la cellule d'origine (références circulaires). Dans ce cas, l'arbre des dépendances est affiché dans le message d'erreur; + \item une formule nécessitant un nombre fait référence à une cellule vide ou ne contenant que du texte; + \item une cellule fait référence à une cellule non définie (hors limite du tableau); + \item une cellule fait référence à une cellule fusionnée par un \verbinline-\multicolumn-; + \item une référence relative entre crochets ne respecte pas la syntaxe. +\end{itemize} + +Le package peut émettre des messages d'information (dans le fichier de log), ce qu'il fait par défaut. La commande \verbinline-\STmessage- permet ou pas l'émission de messages d'information. Pour chacune des ces altenatives, la syntaxe est la suivante : \verbinline-\STmessage{true}- ou \verbinline-\STmessage{false}-. + +Pour comprendre la signification des messages, prenons un tableau simple :\par\nobreak +\begin{minipage}{0.65\linewidth} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|cccc|c|}}\hline +b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline +\end{spreadtab} +\end{lstlisting} +\end{minipage}% +\begin{minipage}{0.35\linewidth} +\centering +\begin{spreadtab}{{tabular}{|cccc|c|}}\hline +b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline +\end{spreadtab} +\end{minipage} + +Le fonctionnement du tableau est ici très simple à comprendre. Voici les informations délivrées par \ST :\par\nobreak +\begin{lstlisting} +[spreadtab] New spreadtab {tabular}{|cccc|c|} +* reading tab: ok +* computing formulas: + cell A1-B1-C1 + cell B1 + cell C1 + cell D1 + cell E1 +* building tab: ok +[spreadtab] End of spreadtab +\end{lstlisting} +L'environnement spécifié par l'utilisateur est repris entre parenthèses (ici \verbinline-{tabular}{|cccc|c|}-). Précédées d'une étoile, on retrouve les 3 étapes nécessaires à \ST pour mener à bien sa mission : lecture du tableau, calcul des formules et construction du tableau final. + +Pour la seconde étape, les cellules sont évaluées de haut en bas, de gauche à droite : \ST indique qu'il commence par essayer de calculer la première cellule \falseverb{A1}. Pour cela, il indique qu'il doit d'abord évaluer \falseverb{B1} et avant cela encore, évaluer \falseverb{C1}. Comme il n'y a plus de cellule après \falseverb{C1}, c'est qu'elle peut être évaluée; en effet, elle ne dépend que de \falseverb{D1} qui est un nombre égal à 10. + +Pour chaque ligne suivante, il n'y a qu'une seule cellule ce qui signifie que lorsque \ST essaie de les évaluer, elles l'ont déjà été et sont des nombres ou alors, elles ne font références qu'à des cellules déjà calculées. + +\subsection{Débogage} +Pour faciliter l'utilisation de \ST, un mode de débogage est disponible. Il est activé lorsque la commande \verbinline-\STdebug- est présente dans l'argument optionnel de l'environnement \verb-spreadtab-. Cette commande change le comportement de \ST qui, au lieu d'afficher le tableau final, affiche un (ou plusieurs) tableau de débogage. Cet affichage se fait juste après que \ST ait lu l'ensemble de toutes les cellules ; aucun calcul de formule n'a encore eu lieu. Il y a autant de tableaux affichés que de commande \verbinline-\STdebug- présentes, sous réserve que leur argument soit différent. Seuls 3 arguments sont possibles, et voici ce qu'il permettent : +\begin{itemize} + \item \verbinline-\STdebug{formula}- : affichage des champs numériques de toutes les cellules et les fins de ligne; + \item \verbinline-\STdebug{text}- : affichage des champs textuels de toutes les cellules; + \item \verbinline-\STdebug{code}- : affichage du code interne que \ST affecte à chaque cellule. Ce code interne est assigné à chaque cellule lors de la lecture du tableau. Il vaut : + \begin{enumerate}[label=\small\textbullet] + \item $-1$ s'il s'agit d'une cellule fusionnée par une commande \verbinline-\multicolumn-; + \item 0 si la cellule est vide ou purement textuelle; + \item 1 si le champ numérique de la cellule contient une formule qui sera à évaluer plus tard; + \item 2 si la champ numérique de la cellule contient un nombre. + \end{enumerate} +\end{itemize} + +Lorsque le mode débogage est activé, le tableau final \emph{n'est pas affiché}. Il est cependant possible de forcer cet affichage en mettant la commande \verbinline-\STdisplaytab- dans l'argument optionnel. + +Voici un tableau sur lequel s'appuiera l'exemple suivant : + +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|r|r|r|}}\hline +@$x$ &@$y$ & @$x+y$\\\hline\hline +22 & 54 & \STcopy{v3}{a2+b2} \\ +43 & 65 & \\ +49 & 37 & \\\hline +$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline +\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|r|r|r|}}\hline +@$x$ &@$y$ & @$x+y$\\\hline\hline +22 & 54 & \STcopy{v3}{a2+b2} \\ +43 & 65 & \\ +49 & 37 & \\\hline +$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline +\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} +\end{spreadtab} +\end{center} +On va demander à ce que \ST affiche les 3 tableaux de débogage possibles concernant le tableau ci-dessus. Pour cela, il suffit de modifier la ligne 1 du code ci-dessus comme ceci : + +\hfill\verbinline[basicstyle=\ttfamily\small]-\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline-\hfill\kern0pt +\begin{center} +\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline +@$x$ &@$y$ & @$x+y$\\\hline\hline +22 & 54 & \STcopy{v3}{a2+b2} \\ +43 & 65 & \\ +49 & 37 & \\\hline +$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline +\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} +\end{spreadtab} +\end{center} +Ces 3 tableaux de débogage peuvent aider à comprendre un peu mieux le fonctionnement interne de \ST. On peut observer dans le tableau 2 que toutes les cellules ayant un champ numérique ont un code interne de 1 ou 2 (voir tableau 3) et ont un marqueur de champ numérique "\verb-:=-" qui leur est associé (voir tableau 1). Ce marqueur représente l'endroit où sera inséré ---~par substitution~--- le résultat du calcul du champ numérique. C'est donc à partir des contenus des champs textuels du tableau 1 et par simple substitution, qu'une fois les champs numériques calculés, les cellules sont reconstituées pour donner celles du tableau final. + +Dans les tableaux ci-dessus, les cellules contenant les coordonnées ne sont grisées que si le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/colortbl/}{\texttt{\textbf{colortbl}}} a été chargé. + +\section{Exemples} +Voici quelques tableaux pour finir ! + +Afin que l'on sache quels nombres sont calculés, seuls les nombres non calculés sont en \textcolor{red}{rouge}. Dans ces tableaux, beaucoup d'artifices (des struts, des multicolumn) et des packages (notamment numprint et ses colonnes \og N\fg{} qui alignent les séparateurs décimaux) ont été utilisés pour obtenir un résultat satisfaisant. Le code est parfois lourd et peu lisible, mais il ne s'agit pas ici d'exemples basiques mais de tableaux peaufinés ! + +\subsection{Encore un triangle de Pascal} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{*7r}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ +[0,1] & [-1,1] & & & & & \\ +\color{red}:={1}& & & & & & +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{*7r}} +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ +[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ +[0,1] & [-1,1] & & & & & \\ +\color{red}:={1}& & & & & & +\end{spreadtab} +\end{center} + +\subsection{Convergence d'une série} +Pour les matheux, il s'agit du développement limité de la fonction exponentielle en \numprint{0.5}. En effet, +\[\forall x\in \mathbf{R}\qquad e^x=\sum_{k=0}^\infty\frac{x^k}{k!}\] +et le tableau illustre la rapidité de la convergence au fur et à mesure de l'ordre du développement limité.\par\nobreak +\begin{lstlisting} +\STautoround{15} +\renewcommand\STprintnum[1]{\numprint{#1}} +\begin{spreadtab}{{tabular}{cc}} +\multicolumn{2}{c}{Convergence en $x=\color{red}:={0.5}$}\\[1.5ex] +@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline +\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ +\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\STautoround{15} +\renewcommand\STprintnum[1]{\numprint{#1}} +\begin{spreadtab}{{tabular}{cc}} +\multicolumn{2}{c}{Convergence en $x=\color{red}:={0.5}$}\\[1.5ex] +@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline +\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ +\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\ + & & \\\hline +\end{spreadtab} +\end{center} + +\subsection{Convergence vers le nombre d'or} +Voici la définition des nombres de Fibonacci : $F_0=1\qquad F_1=1\qquad F_{n+2}=F_{n+1}+F_n$ + +On va mettre ici en évidence que le quotient de 2 nombres de Fibonacci consécutifs $F_n$ et $F_{n-1}$ tend vers le nombre d'or $\varphi=\frac{1+\sqrt{5}}{2}$ de telle sorte que la suite $u_n=\varphi-\frac{F_n}{F_{n-1}}$ soit alternativement positive et négative.\par\nobreak +\begin{lstlisting} +\STautoround{9} +$\begin{spreadtab}{{array}{ccN39N{3}{9}}} +@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline +\color{red}:=1 & \color{red}:=1 & & \\ +\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ + & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\\hline +\end{spreadtab}$ +\end{lstlisting} +\begin{center} +\STautoround{9} +$\begin{spreadtab}{{array}{ccN39N{3}{9}}} +@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline +\color{red}:=1 & \color{red}:=1 & & \\ +\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ + & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\ + & & & \\\hline +\end{spreadtab}$ +\end{center} + +\subsection{Tableau de facturation} +Voici un tableau de facturation, où les séparateurs décimaux sont alignés dans les colonnes grâce au spécificateur de colonne \og N\fg{} du package \falseverb{numprint}. + +Ce tableau est généré par l'environnement \verb=tabularx= de façon à occuper 80\% de la largeur de la ligne. La commande \verbinline=\multicolumn= a été largement utilisée pour la mise en forme :\par\nobreak +\begin{lstlisting} +\nprounddigits2 +\let\PC\% +\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} +\newcommand\RED{\color{red}} +\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} +\hline +@D\'esignation &@\multicolumn1c{Prix U}& @\multicolumn1c{Qt\'e} & @\multicolumn1c{Prix} & @\multicolumn1c{R\'eduction} & @\textbf{\`A payer}\\\hline +@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline +@\multicolumn6c{}\\[-1.5ex]\cline{4-6}% ligne vide et on remonte un peu ! +@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ +\cline{4-6} +\end{spreadtab} +\end{lstlisting} +\begin{center} +\nprounddigits2 +\let\PC\% +\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} +\newcommand\RED{\color{red}} +\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} +\hline +@D\'esignation &@\multicolumn1c{Prix U}& @\multicolumn1c{Qt\'e} & @\multicolumn1c{Prix} & @\multicolumn1c{R\'eduction} & @\textbf{\`A payer}\\\hline +@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ +@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline +@\multicolumn6c{}\\\cline{4-6}% ligne vide et on remonte un peu ! +@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ +\cline{4-6} +\end{spreadtab} +\end{center} + +\subsection{Carré magique} +\begin{lstlisting} +\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} +\hline +\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline +2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline +4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} +\hline +\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline +2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline +4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline +\end{spreadtab} +\end{center} + +\subsection{Pyramide additive} +Chaque nombre est la somme des deux nombres se trouvant au dessous de lui.\par\nobreak +\begin{lstlisting} +\newlength\cellsize +\setlength\cellsize{1.5cm} +\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} +\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} +\cline{4-5} +&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} +&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} +&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline +\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline +\end{spreadtab} +\end{lstlisting} +\begin{center} +\newlength\cellsize +\setlength\cellsize{1.5cm} +\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} +\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} +\cline{4-5} +&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} +&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} +&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline +\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline +\end{spreadtab} +\end{center} +\medskip +\parskip0pt +\begin{center} +$\star$\par +$\star\quad\star$ +\end{center} +C'est tout, j'espère que cette extension vous sera utile !\par\nobreak\medskip + +Je vous remercie d'avance de me signaler par \href{mailto:unbonpetit@netc.fr}{\texttt{\textbf{email}}} tout bug, toute macro-fonction à implémenter que vous pensez utile ou toute proposition d'amélioration \emph{réaliste} : il ne faut pas oublier que cette extension doit rester modeste, que \ST n'est pas excel ou calc et qu'il est impossible d'implémenter toutes les fonctionnalités avancées de ces tableurs.\par\nobreak\bigskip +Christian \textsc{Tellechea} +\end{document} \ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.pdf b/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.pdf deleted file mode 100644 index 759e167b548..00000000000 Binary files a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.tex b/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.tex deleted file mode 100644 index 596e7837bbf..00000000000 --- a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_en.tex +++ /dev/null @@ -1,1602 +0,0 @@ -% ____________________________________________________________________________ -% | | -% | | -% | spreadtab v0.4c | -% | | -% | 6 november 2014 | -% | | -% |___________________________________________________________________________| -% -% This file is spreadtab_doc_en.tex, the source code of the english manual of -% the spreadtab package. -% -% Copyright Christian Tellechea 2009-2014 -% email : unbonpetit@openmailbox.org -% -% ------------------------------------------------------------------- -% This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% -% http://www.latex-project.org/lppl.txt -% -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% ------------------------------------------------------------------- -\documentclass[a4paper,10pt]{article} -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} -\usepackage{libertine} -\renewcommand*\oldstylenums[1]{{\fontfamily{fxlj}\selectfont #1}} -\usepackage[scaled=0.8]{luximono} -\usepackage[a4paper,margin=2.6cm]{geometry} -\usepackage{amsmath,amssymb} -\usepackage{textcomp} -\usepackage{array} -\usepackage[table]{xcolor} -\usepackage{arydshln} -\usepackage{tabularx} -\usepackage{xcolor} -\usepackage{listings} -\usepackage[autolanguage]{numprint} -\usepackage{xspace} -\usepackage[bottom]{footmisc} -\usepackage{spreadtab} -\usepackage[protrusion=true,final,verbose=true,babel=true]{microtype} -\usepackage{fancyhdr} - \fancyhead[L]{} - \fancyhead[C]{\small\bfseries\ST} - \fancyhead[R]{\scriptsize\slshape \leftmark} - \fancyfoot[l]{\tiny \LaTeX ed by Christian \textsc{Tellechea}, the \today.} - \fancyfoot[c]{} - \fancyfoot[r]{\thepage} -\usepackage[english]{babel} - -\usepackage{enumitem} -\makeatletter -\definecolor{ST@bckgcolor}{rgb}{0.87,0.9,1} -\definecolor{ST@codebckgcolor}{rgb}{0.9,0.9,0.9} -\definecolor{ST@keywordstc}{rgb}{0.7,0,0} -\definecolor{ST@keywordslatex}{rgb}{0,0,1} -\definecolor{ST@arguments}{rgb}{0,0,0} -\definecolor{ST@comments}{rgb}{0.5,0.5,0.5} -\lstset{% - language=[AlLaTeX]TeX,float=hbp,basicstyle=\footnotesize\ttfamily,identifierstyle=\color{ST@arguments},% - keywordstyle=\color{ST@keywordslatex},commentstyle=\itshape\color{ST@comments},% - columns=fixed,tabsize=4,frame=single,extendedchars=false,% - showspaces=false,showstringspaces=false,numbers=left,numberstyle=\tiny\ttfamily,% - breaklines=true,breakindent=3em,backgroundcolor=\color{ST@bckgcolor},breakautoindent=true,% - captionpos=t,xleftmargin=1em,xrightmargin=1em,lineskip=0pt,% - numbersep=1em,classoffset=1,% - morekeywords={% les macros et commandes de spreadtab - spreadtab,endspreadtab,SThiderow,SThidecol,STsavecell,STautoround,STmessage,STsetdecimalsep,STtransposecar,STdebug,STdisplaytab,STsetdisplaymarks,% - STnumericfieldmarker,STprintnum,STtextcell,STcopy,STtag,STmakegtag,STeol,fact,id,ifeq,ifgt,iflt,numtofrshortdate,% - numtoengshortdate,numtofrlongdate,numtoenglongdate,numtofrmonth,% - numtoengmonth,numtofrday,numtoengday,sum,rand,randint,sumprod,% - frshortdatetonum,engshortdatetonum,englongdatetonum,frlongdatetonum,gcd,lcm,tag,cell,row,col},% - keywordstyle=\color{ST@keywordstc},classoffset=0} - -%%%%%%%%%%% environnement OOcalc -\newcount\cntlin -\newcount\cntcol - -\newtoks\t@b -\long\def\ifremain@lines#1\\#2\@nil{% - \csname @\ifx\@empty#2\@empty second\else first\fi oftwo\endcsname} -\long\def\subst@eol#1\\#2\@nil{\addtot@b{#1\\\cline{1-1}\hdashline}% - \ifremain@lines#2\\\@nil{\addtot@b&\subst@eol#2\@nil}{\addtot@b{#2\end{tabular}}}} -\long\def\collect@body#1\end{\subst@eol#1\@nil\end} - -\newcommand\addtot@b[1]{\t@b\expandafter{\the\t@b#1}} -\newcommand\edftot@b[1]{\edef\temp@{#1}\expandafter\addtot@b\expandafter{\temp@}} - -\newenvironment{OOocalc}[2][1.5cm]{% #1=largeur colonnes #2 = nombre de colonnes - \newcolumntype w{>{\centering\arraybackslash}m{#1}}% - \arrayrulewidth0.4pt\dashlinedash0.4pt\relax\dashlinegap3pt - \global\cntlin\m@ne\global\cntcol\z@ - \tabfont - \tabcolsep0pt - \t@b{\begin{tabular}{% - |>{\cellcolor{tabheadcolor}% - \global\cntcol\z@\global\advance\cntlin\@ne - \centering\arraybackslash - \ifnum\cntlin>\z@\tableheadformat\number\cntlin\fi} - m{2em}|*{#2}{w:}}% - \hline - \rowcolor{tabheadcolor}}% - \loop - \ifnum\cntcol<#2 - \advance\cntcol\@ne - \addtot@b{&\multicolumn{1}{>\centering m{#1}|}}% - \edftot@b{{\noexpand\tableheadformat\@Alph\cntcol}}% - \repeat - \addtot@b{\\\hline&}% - \collect@body}{\the\t@b} -\makeatother - -% commandes de personnalisation de OOcalc -\newcommand*\tabfont{\fontfamily{phv}\selectfont\footnotesize}% police du tableau (helvetica ici) -\newcommand*\tableheadformat{\bfseries}% police des en-têtes du tableau (en gras) -\colorlet{tabheadcolor}{gray!40}% couleur de font des en-têtes du tableau -\colorlet{palepink}{pink!80} -\colorlet{lightpink}{pink!30} -\colorlet{palegreen}{green!60} -\colorlet{lightgreen}{green!30} -\newcommand\CC[1]{\cellcolor{#1}} - -\newcommand\verbinline[1][]{\lstinline[breaklines=false,basicstyle=\normalsize\ttfamily,#1]} -\newcommand\ST{\textsf{spreadtab}\xspace} -\newcommand\falseverb[1]{\texttt{\detokenize{#1}}} - -\usepackage[bookmarks=true,bookmarksopen=true,colorlinks=true,hyperfootnotes=false,filecolor=black,linkcolor=blue,urlcolor=magenta,pdfauthor={Christian TELLECHEA},pdftitle={spreadtab},pdfsubject={Spreadtab provides spreadsheet features for LaTeX table environments},pdfkeywords={spreadtab},pdfcreator={LaTeX}]{hyperref} - -\begin{document} -\parindent0pt\pagestyle{fancy} -\begin{titlepage} - \null\par\vfill - \begin{center} - \begin{minipage}{0.75\linewidth} - \begin{center} - \Huge\bfseries \ST\par\vspace{5pt} - \small v\csname ST@ver\endcsname\par\vspace{25pt} - \normalsize User's manual - \end{center} - \end{minipage} - \end{center} - \vspace{1cm} - \begin{center} - Christian {\sc Tellechea}\par\small - \href{mailto:unbonpetit@openmailbox.org}{\texttt{\textbf{unbonpetit@openmailbox.org}}}\par\vspace{5pt} - \csname ST@eng@date\endcsname - \end{center} - \vfill - \begin{center} - \begin{minipage}{0.8\linewidth} - \noindent\hrulefill\par - \hfill\textbf{\textit{Abstract}}\hfill{}\medskip\par\footnotesize - This package provides spreadsheet features for \LaTeX{} table environments.\par\medskip - The main feature allows the user to construct tables in a manner similar to a spreadsheet where cells are used in formulas to generate values in other cells. The package computes the formulas in the correct order and finally displays the table with the numeric results.\par - \hrulefill - \end{minipage} - \end{center} -\vfill{} -\end{titlepage} - -\tableofcontents\newpage -\parskip\medskipamount -\section{Introduction} - -\subsection{Presentation} -This package allows us to construct tables in a manner similar to a spreadsheet. The cells of a table have row and column indices and these can be used in formulas to generate values in other cells. - -The package requires $\varepsilon$-\TeX, \LaTeXe{} and the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} package, which performs arithmetic on cell values. Also, the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/xstring/}{\texttt{\textbf{xstring}}} package is needed in its \falseverb{v1.5d [2010/03/28]} version or later.\medskip - -The package is compatible with \emph{all} tabular environments, and assumes that `\verb=&=' is used to delimit columns and `\verb-\\-' to end lines (but see page~\pageref{STeol}). This compatibility requirement led me to program \ST so that it works independently of the table environment. Thus, reading the table, processing and calculating the formulas is done \emph{before} the environment table `sees' the body of the table.\medskip - -Consequently, \ST proceeds in 3 main stages before \verbinline=\begin{
}= sees the table: -\begin{itemize} - \item first, it reads the body of the table, divides it in lines and cells, and in each cell, seeks a possible formula; - \item then, it computes the formulas in the cells, taking care for each to previously calculate all the dependent cells. The calculations are done by the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} package; - \item finally, it is necessary to rebuild the table, replacing each formula by its numerical calculated value and handing over to the environment name specified by the user. -\end{itemize} -The syntax in both the following is allowed (and equivalent), where \verb-- is the name of any table environment available with \LaTeX{} or with a package:\par\nobreak -\begin{minipage}{0.48\linewidth} -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\begin{spreadtab}{{}{}} - table with formulas and numbers -\end{spreadtab} -\end{lstlisting} -\end{minipage}\hfill or\hfill -\begin{minipage}{0.48\linewidth} -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\spreadtab{{}{}} - table with formulas and numbers -\endspreadtab -\end{lstlisting} -\end{minipage} - -After the work of \ST, we get a display as if we had written: -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\begin{}{} - table with numbers -\end{} -\end{lstlisting} - -Although having features resembling those of a spreadsheet with \LaTeX{} is appreciable, the 3 stages described above take time, and above all, \verb-fp- is slow in its calculations. The \ST environment leads to \emph{much slower compilation} than with a classical table. - -Moreover, \ST \emph{cannot stand in for a spreadsheet program}. Indeed, it has very few features, and it does not provide visual assistance. This point may cause difficulty\footnote{I certify that, with use, this discomfort tends to disappear (if you do not work with huge tables, of course).} for big or complex tables. The syntax of \ST is also another difficulty. However, the advantage of this package is that it makes it possible to write \emph{in the \LaTeX{} code} tables involving calculation when these tables are usually exported\footnote{I mention the two main exportation programs: \href{http://calc2latex.sourceforge.net/}{\texttt{\textbf{cacl2latex}}} for `calc' (Open Office), and \href{http://www.ctan.org/tex-archive/support/excel2latex/}{\texttt{\textbf{excel2latex}}} for `excel' (Microsoft Office).} from a spreadsheet program to \LaTeX{} code. Consequently, it becomes possible to avoid the disadvantages of the exportation programs: fine tuning often necessary to obtain exactly what you want, exported tables containing the values only (formulas are lost when exportation is done), no compatibility with all types of environments, exportation must be started again if a single number or formula is modified in the table. - -\subsection{Motivation} -A few months before I started to write this package, Derek \textsc{O'Connor} had pointed out that nothing was available in the world of \LaTeX{} packages to imitate --~even a little~-- the behaviour of spreadsheet programs. I found the challenge interesting and I started writing this package as a good programming exercise. - -The road was long before reaching this version and I especially want to thank Christophe \textsc{Casseau} for his early interest and for the suggestions he made, and more recently Derek \textsc{O'Connor} for his advice and for the constructive discussions we have had. I also thank Andrew \textsc{Parsloe} for proofreading the english translation of this manual. - -\section{Basic features} -A table is a rectangular array of cells which may be viewed as a set of cells arranged in horizontal rows or vertical columns. - -\label{STeol}By default, \ST expects a `\verb-\\-' at the end of lines, which is usual in tables. This end of line marker can be changed via the \verbinline-\STeol{}- command. We can write for example \verbinline-\STeol{\tabularnewline}-. It is important to remember that the ends of lines to be inserted in the final table will always be `\verb-\\-' even if the end of line marker that \ST sees when it \emph{reads} the table is different. - -\subsection{Absolute references} -A table cell is identified by the pair \falseverb{}\footnote{Note: this is the opposite to the standard matrix convention}, where: -\begin{itemize} - \item \verb|| is a letter from \falseverb a to \falseverb z, and \falseverb a is the first column on the left: it is limited to 26 columns, which should be sufficient for the majority of cases; the letter can be upper or lowercase; - \item \verb|| is a positive integer representing row number. The row number 1 is the top row. -\end{itemize} -Here are examples of absolutes references: \falseverb{b4} or \falseverb{C1} or \falseverb{d13}. Locations of cells appear clearly in the spreadsheet-like table below: -\begin{center} -\begin{OOocalc}[6em]{5} -&&&&\\&&&&\\&&&&\\&&&&\\&&&&\\ -\end{OOocalc} -\end{center} -This example calculates the sum of each row and each column and then calculates the grand total:\par\nobreak -\begin{minipage}{0.75\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{rr|r}} -22 & 54 & a1+b1 \\ -43 & 65 & a2+b2 \\ -49 & 37 & a3+b3 \\ -\hline -a1+a2+a3 & b1+b2+b3 & a4+b4 -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.25\linewidth} -\centering -\begin{spreadtab}{{tabular}{rr|r}} -22 & 54 & a1+b1 \\ -43 & 65 & a2+b2 \\ -49 & 37 & a3+b3 \\ -\hline -a1+a2+a3 & b1+b2+b3 & a4+b4 -\end{spreadtab} -\end{minipage}% - -For people familiar with maths, this other example calculates the first lines of Pascal's triangle:\par\nobreak -\begin{minipage}{0.75\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{ccccc}} -1 & & & & \\ -a1 & a1 & & & \\ -a2 & a2+b2 & b2 & & \\ -a3 & a3+b3 & b3+c3 & c3 & \\ -a2 & a4+b4 & b4+c4 & c4+d4 & d4 -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.25\linewidth} -\centering -\begin{spreadtab}{{tabular}{ccccc}} -1 & & & & \\ -a1 & a1 & & & \\ -a2 & a2+b2 & b2 & & \\ -a3 & a3+b3 & b3+c3 & c3 & \\ -a2 & a4+b4 & b4+c4 & c4+d4 & d4 -\end{spreadtab} -\end{minipage}% - -\subsection{Relative references} -To refer to a cell, it may be convenient to specify its position relative to where the formula is written. Thus, the relative coordinates of a cell are 2 relative numbers written using this syntax: \falseverb{[x,y]} where \falseverb x is the horizontal offset from the cell containing the formula and \falseverb y is the vertical offset. For example, \falseverb{[-2,3]} refers to the cell located 2 columns before (on the left) and 3 rows after (below) the cell where the formula is located. - -Here is the same table as above but the references are relatives and the \verbinline-matrix- environment of the \href{http://www.ctan.org/tex-archive/macros/latex/required/amslatex/math/}{\texttt{\textbf{amsmath}}} package is used:\par\nobreak -\begin{minipage}{0.82\linewidth} -\begin{lstlisting} -$ -\begin{spreadtab}{{matrix}{}} -1\\ -[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] -\end{spreadtab} -$ -\end{lstlisting} -\end{minipage}\hfill -\begin{minipage}{0.15\linewidth} -\centering -$ -\begin{spreadtab}{{matrix}{}} -1\\ -[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] -\end{spreadtab} -$ -\end{minipage}% - -We note that relative references are more appropriate here, since only 2 different references are used: \falseverb{[0,-1]} which refers to the cell above and \falseverb{[-1,-1]} which refers to the cell located to the NW of the current cell.\medskip - -Absolute and relative references can be mixed in a formula. - -\subsection{Text cells} -If you want to put only text in a cell, you must tell \ST that the cell should not be calculated. Simply place somewhere in the cell the character `\falseverb @' with its usual catcode 12. The cell will be ignored by \ST which will consider it as an inert cell impossible to reference\footnote{There is an exception, see page \pageref{datetonum}.} elsewhere in the table. - -Example:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ values of $x$ & -5 & -1 & 4 \\ -@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ values of $x$ & -5 & -1 & 4 \\ -@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline -\end{spreadtab} -\end{center} -The control sequence \verbinline=\STtextcell= expands to the character `\falseverb @'. It is possible to redefine it; for example, after \verbinline-\renewcommand\STtextcell{`}-, a cell containing the char \verb=`= will be understood as a text cell. - -Moreover, if a cell is empty or filled with spaces, \ST will consider it as a text cell. - -\subsection{Mixed cells} -In reality, each cell is composed of two fields. The first is a \emph{numeric field} containing the formula; the second is a \emph{text field}, ignored by \falseverb{fp} and not taken into account for calculations: -\begin{itemize} - \item if nothing is specified in a cell, the entire cell is the number field, and the text field is empty (this was the case for all table cells of Pascal's triangle seen above); - \item if the cell contains the `\falseverb @' character, then the entire cell is the text field. The numeric field is empty and inaccessible; - \item if the cell contains the marker `\verb-:=-', then the following argument between braces is the numeric field, and everthing else is the text field. The cell has this structure:\par - \hfil\verb-:={numeric field}-\hfil\null\par - The marker `\verb-:=-' is the expansion of the control sequence \verbinline-\STnumericfieldmarker-. It is possible to redefine it, for example:\par\smallskip - {\centering\verbinline-\renewcommand\STnumericfieldmarker{\=}-\par\smallskip} - In this case, the expansion of the marker `\verb-\=-' would have no importance and would not be involved in the process. For \ST, it is only a token showing where the formula begins. This token is sought and recognized but is never expanded. -\end{itemize} -Once the \falseverb{numeric field} is computed, `\falseverb{:={numeric field}}' is replaced by the numeric value. - -Note that `\verb-:={numeric field}-' may be inside brackets, whatever be the level of nesting. For example, if a cell contains \verb-\textbf{:={a1+1}}- and if the numeric value of the cell \falseverb{a1} is 5, then finally, the cell will contain \verb-\textbf{6}-\medskip - -Here is a simple example:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -value 1 : :={50} & value 2 : :={29} & average : \textbf{:={(a1+b1)/2}}\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -value 1 : :={50} & value 2 : :={29} & average : \textbf{:={(a1+b1)/2}}\\\hline -\end{spreadtab} -\end{center} -If `\verb-:=-' is written in a cell with an empty argument like this `\verb-:={}-', then the cell is understood as a text cell. In fact, `\verb-:={}-' behaves like `\verb-@-', but they are \emph{not} equivalent: `\verb-:={}-' allows the cell to receive a formula from another with \verbinline-\STcopy- (see next section) while it is impossible with `\verb-@-'. - -\subsection{Copy a formula} -To avoid having to copy formulas into adjacent cells, the \ST package provides the \verbinline-\STcopy- command. - -This command must be written in a cell with this syntax: -\begin{center} -\verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formula}- -\end{center} -where $x$ and $y$ are positive numbers that represent horizontal and vertical offsets relative to the cell where the command is. With the cell containing the command (the source cell), these offsets define a range of cells which will receive the \verb--\footnote{The copy can only be done to cells located on the right and below the cell containing the macro.}. The command \verbinline-\STcopy- must \emph{not} be in a cell where there is a numeric field marker `\verb-:=-'. - -Here is how the copy is made: it starts from the cell where the command \verbinline-\STcopy- is. For the other cells, all the coordinates in the formula are modified taking into account the offsets from the source cell. For example, if the source cell contains the formula \verb-a1+b2+c3-, and the target cell is located 2 columns rightwards and 5 rows below then, this formula becomes: \verb-c6+d7+e8-. The formula can also contain relative references but, since they are relative, they are not modified. - -Preceded by `\verb-!-', a coordinate in a formula is not modified when the formula is copied. For example, if the source cell contains \verb-a!1+!b2+!c!3- and the target cell is located 2 columns rightwards and 5 rows below then, this formula becomes: \verb-c1+b7+c3-. The feature is compatible with relative coordinates. Let's suppose a cell contains this formula: \verb|[-1,!-1]+[!-1,1]+[!1,!2]|. As usual, let's say that this formula is copied to the cell located 2 columns rightwards and 5 rows below: this formula becomes: \verb|[-1,-6]+[-3,1]+[-1,-3]|. - -The `\verb-!-' character is the expansion of the control sequence \verbinline-\STtransposecar-. It may be changed to any other with \verbinline-\renewcommand\STtransposecar-\verb-{}-. The `\verb-!-' character, used by default, keeps its 13 catcode and remains active if the \verb-babel- package is loaded with the \verb-frenchb- option. - -In `\verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formula}-', if $x$ is omitted, the copy is made to the cells rightwards, up to the right edge of the table. With $y$, it is the same: if this number is omitted, the copy is done to the cells below until the bottom of the table is reached. If $x$ or $y$ is equal to 0, the copy is limited to the column or row of the source cell. Instead of writing \verb-v0- or \verb->0-, it is possible to write \verb-v- or \verb->-. - -Here are some examples: -\begin{tabular}{cl}\hline -\verb-{>3,v1}- & copy to 3 columns rightwards and 1 row below\\ -\verb-{>3}- & copy to 3 cells on the right\\ -\verb-{v1}- & copy to the cell below\\ -\verb-{>}- & copy rightwards up to the right edge\\ -\verb-{v}- & copy below\\ -\verb-{v,>}- & copy to the right and below until the end of the table\\\hline -\end{tabular} - -It is easy to generate the multiplication table from 1 to 10: - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} -\hline -@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline -1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ -\STcopy{v}{a2+1} & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} -\hline -@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline -1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ -\STcopy{v}{a2+1} & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\\hline -\end{spreadtab} -\end{center} - -If the numeric field of a target cell is not empty, it is not replaced and the copy is not done for this cell. - -If 2 or more \verbinline-\STcopy- commands in several source cells have the same target cell, then, the formula this latter receives is the one contained in the last \verbinline-\STcopy- command when the table is read from top left to bottom right. In the spreadsheet-like example below, the \verbinline-\STcopy- in the pink cell \falseverb{B1} has its target range partially covered by the one of the green cell \falseverb{C3}. -\begin{center} -\begin{OOocalc}[2.3cm]{6} -1 &\CC{palepink}\ttfamily\textbackslash STcopy \{v,>\}\{!a1+1\} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} \\ -2 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} ~\par~ \\ -3 &\CC{lightpink} &\CC{palegreen}\ttfamily\textbackslash STcopy \{>2,v1\}\{!a3*10\}&\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink} \\ -4 &\CC{lightpink} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink}~\par~ \\ -5 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink}~\par~ \\ -\end{OOocalc} -\end{center} -Here is this example, treated by \ST below. In this table, the cell \verb-b5- (numeric field alone) and the cell \verb-c5- (text field + numeric field) stay unchanged since their numeric fields are not empty: -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 &\STcopy{v,>}{!a1+1} & & & & \\\hline -2 & & & & & \\\hline -3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline -4 & & & & & \\\hline -5 & -1 & a:={0}b & & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 &\STcopy{v,>}{!a1+1} & & & & \\\hline -2 & & & & & \\\hline -3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline -4 & & & & & \\\hline -5 & -1 & a:={0}b & & & \\\hline -\end{spreadtab} -\end{center} -As mentioned in the last chapter, you can also copy a formula to a text cell containing an empty numeric field (that is to say a cell containing `\verb-:={}-'). In this case, the formula is copied inside the brackets. On the other hand, a cell containing text `\verb-@-' cannot receive a formula when copying and the cell remains purely textual. - -Example : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 & 2 & 3 & 4 & 5 & 6 \\\hline -X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 & 2 & 3 & 4 & 5 & 6 \\\hline -X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline -\end{spreadtab} -\end{center} - -\section{Features for formatting the table} -\subsection{Decimal seprarator} -The \verb-fp- package returns its results with the decimal point separator. After the job of \verb-fp-, \ST can change this decimal separator: everything happens as if the results returned by \verb-fp- were taking this into account. The command \verbinline-\STsetdecimalsep- takes a mandatory argument which is the character used as decimal separator: -\begin{center} -\verbinline-\STsetdecimalsep-\verb-{}- -\end{center} -For example, French users should write this in the preamble of the document: -\begin{center} -\verbinline-\STsetdecimalsep{,}- -\end{center} -For numeric fields located in math mode, the comma is considered as a math punctuation, which explains why it is followed by a space. To pevent this behaviour, it can be written inside brackets: - -\begin{minipage}{0.65\linewidth} -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -3,14 is not displayed like $3,14$.\par -3,14 is displayed like $3{,}14$ -\end{lstlisting} -\end{minipage}\hfill -\begin{minipage}{0.35\linewidth} -3,14 is not displayed like $3,14$.\par -3,14 is displayed like $3{,}14$ -\end{minipage}% - -When cells are in math mode, you can\footnote{It is preferable to use the \texttt{numprint} package to format the results. You can also change the math code of the comma: \texttt{\textbackslash mathcode`,="013B\textbackslash relax}. This trick puts the comma in the class 0 of the ordinary signs while its natural class is 6 (punctuation signs).} use this feature and ask \ST to replace the decimal point by a comma inside braces with the command \verbinline-\STsetdecimalsep{{,}}-. In these tables where each cell is in math mode, the space after the commas are neutralized in the second table: - -\begin{minipage}{0.65\linewidth} -\begin{lstlisting} -\STsetdecimalsep{,} -\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline -@x & @y & @\text{Average}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab}\par\smallskip -\STsetdecimalsep{{,}} -\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline -@x & @y & @\text{Average}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.35\linewidth} -\centering -\STsetdecimalsep{,} -\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline -@x & @y & @\text{Average}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab}\par\smallskip -\STsetdecimalsep{{,}} -\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline -@x & @y & @\text{Average}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab} -\end{minipage} - -\subsection{Number formatting and the {\ttfamily fp} package} -All calculations are made by the \verb-\FPeval- macro\footnote{This macro accepts infix or postfix notation. Consequently, both can be used to write formulas in a cell. For example the infix formula `\falseverb{a1+b1}' is equivalent to the postfix ones `\falseverb{a1 b1 add}' or `\falseverb{a1 b1 +}'.} of the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} package. This package provides all necessary arithmetical functions along with various scientific and trigonometric functions. Calculations are made with 18 decimal digits of precision, and \falseverb{fp} displays \emph{all} the decimals! - -The number of digits displayed can be controlled in various ways: -\begin{itemize} - \item the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/numprint/}{\texttt{\textbf{numprint}}} package can be used in order to properly display numbers; - \item \verb=fp= can round or truncate numbers with \verb-round(number,integer)- or \verb-trunc(number,integer)- but the syntax makes this tedious to write if this is needed for many cells; - \item \ST can round \emph{all} the numbers in the table with the macro \verbinline-\STautoround- whose argument is number of digits in the decimal part. If the argument is empty, no rounding is done. If the starred macro \verbinline-\STautoround*- is used, the decimal part is filled with 0 as necessary. -\end{itemize} -In this example, floating point numbers are rounded to 6 digits:\par\nobreak -\begin{lstlisting} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab}\medskip - -\STautoround*{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab}\medskip - -\STautoround*{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab} -\end{center} - -All the numbers contained in the final table, either typed as is or coming from a calculation are processed by the macro\verbinline-\STprintnum-. By default, this macro has no effect on its argument and is defined this way: -\begin{center} - \verbinline-\newcommand\STprintnum[1]{#1}- -\end{center} -It is possible to round all the numbers via the \verbinline-\numprint- command from the \verb-numprint- package. To achieve this, the \verbinline-\STprintnum- command must be redefined:\par\nobreak -\begin{lstlisting} -\renewcommand\STprintnum[1]{\numprint{#1}} -\nprounddigits{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\renewcommand\STprintnum[1]{\numprint{#1}} -\nprounddigits{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{center} - -Here is another similar example where we test if the number to display is negative with the command \verbinline-\FPifneg- from the \verb-fp- package. If this happens, the number is displayed in red. The command \verbinline-\STautoround- was preferred to \verbinline-\nprounddigits- from the \verb-numprint- package because the latter adds unnecessary 0's. -\begin{lstlisting} -\STsetdecimalsep{.} -\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} -\STautoround{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STsetdecimalsep{.} -\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} -\STautoround{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{center} - -\subsection{End of lines and horizontal rules} -\ST recognizes the usual line breaks and horizontal rules \verb|\\| and \verb|\hline|. It is also possible to specify the optional argument in line break: \verb-\\[]-. - -For horizontal rules, it is possible to use:\par\nobreak -\begin{itemize} - \item \verb-\hline-; - \item \verb=\cline{x-y}= where \falseverb x and \falseverb y define the start and the end of the rule; - \item \verb=\hhline{}= where \verb== is the type of rule (read the manual of the \href{http://www.ctan.org/tex-archive/macros/latex/required/tools/}{\texttt{\textbf{hhline}}} package). - \item any command of the \href{http://www.ctan.org/tex-archive/macros/latex/contrib/booktabs/}{\texttt{\textbf{booktabs}}} package: \verb-\toprule-, \verb-\midrule-, \verb-\bottomrule-, \verb-\cmidrule-, \verb-\addlinespace-, \verb-\morecmidrule- and \verb-\specialrule-. All the arguments of these macros, optional or mandatory are taken into account; - \item \verbinline-\noalign- and its mandatory argument can be written after \verb-\\-. -\end{itemize} -Example: -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*5c}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline -[0,1] & [-1,1] & & & \\ \cline{2-4} -1 & & & & \\ \hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{*5c}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline -[0,1] & [-1,1] & & & \\ \cline{2-4} -1 & & & & \\ \hline -\end{spreadtab} -\end{center} - -\subsection{Hide a row or column} -Sometimes, a column or a row is intended for intermediate calculations and does not need to be displayed in the final table. For this, \ST provides two control sequences \verbinline=\SThiderow= and \verbinline=\SThidecol= which, when placed in a cell, hide the row or column that contains the cell. - -An example:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ values of $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline -@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ -@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ -@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ values of $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline -@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ -@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ -@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline -\end{spreadtab} -\end{center} -The row containing $g(x)$ and column corresponding to the value 0 are hidden. - -Remember that the hidden rows and columns are \emph{invisible} to the tabular environment chosen by the user. Thus, only 4 columns have been defined (\falseverb{|r|ccc|}) and not 5 as seen by \ST. - -Just to see the difference, here is the table obtained when setting 5 columns in the preamble and not hiding any row or column:\par\nobreak -\begin{center} -\begin{spreadtab}{{tabular}{|r|cccc|}} -\hline -@ values of $x$ & -1 & 0 & 2 & 3 \\\hline -@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ -@$g(x)=x-10$ & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ -@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline -\end{spreadtab} -\end{center} - -\subsection{Save the result of a cell} -It may be necessary to save the numerical value of a cell to display it outside a formula or even outside the table. Here is how to do it: -\begin{center} -\verbinline-\STsavecell{}{}- -\end{center} -With a \verbinline-\global\def-\footnote{The \texttt{\string\def} command does not check if the macro it defines already exists.}, this command globally saves in \falseverb{} the result of the formula contained in the cell \falseverb{}.\medskip - -Only absolute references can be used since this command must be placed in the optional argument of the \verbinline-spreadtab- environment. - -Example:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} -\hline -10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline -\end{spreadtab} -\par\medskip -Here is the cell c1 : \result -\end{lstlisting} -\begin{center} -\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} -\hline -10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline -\end{spreadtab} -\par\medskip -Here is the cell c1 : \result -\end{center} -In order to save several cells, the command \verbinline-\STsavecell- can be put several times in the optionnal argument. - -Example:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline -@Speed (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ -@distance (km) & & & & 180\\\hline -@Time (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline -\end{spreadtab}\par\medskip -It lasts more than \hhh\ hours. -\end{lstlisting} -\begin{center} -\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline -@Speed (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ -@distance (km) & & & & 180\\\hline -@Time (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline -\end{spreadtab}\par\medskip -It lasts more than \hhh\ hours. -\end{center} - -\subsection{Display the value of a cell} -In order to display the numeric field of a cell in a textual field, we have seen that we could save this value in a control sequence and use this control sequence anywhere in the table. The process is somewhat tedious\ldots{} Indeed, \verbinline-\STsavecell- is not intended to be used in such a way. Its aim is to save the value of a numeric field for further use \emph{outside} the table. - -There is a simpler way to display the numeric field of a cell in a textual field using the syntax \verb-<>- which is replaced by the numeric field of the cell \verb-reference-, where the \verb-reference- can be absolute or relative. If the text between \verb-<<- and \verb->>- is not a reference, then \verb-<>- is left as is. The \verb-reference- must not contain any space; for example, if you write \verb-<< a1>>-, \ST does not uderstand it as a reference because of the space before `\verb-a1-'. - -Example in a textual cell \verb-a3-: -\begin{lstlisting} -\begin{spreadtab}{{tabular}{lr}} -@Sell price & 250 \\ -@Purchase price & 216 \\\hline -@Profit (<>-<>) & b1-b2 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{lr}} -@Sell price & 250 \\ -@Purchase price & 216 \\\hline -@Profit (<>-<>) & b1-b2 -\end{spreadtab} -\end{center} -Example in the mixed cell \verb-c1-: -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -23 & 32 & Average $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -23 & 32 & Average $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline -\end{spreadtab} -\end{center} -The characters used to delimit the reference are set to `\verb-<<-' and `\verb->>-' by default. They can be modified with the \verbinline-\STsetdisplaymarks- command whose arguments contain the left and right delimiters. For example, if you write \verbinline-\STsetdisplaymarks{|}{|}-, you will write \verb-|reference|- in order to display the content of the numeric field of the cell \verb-reference-. - -\subsection{The use of \ttfamily\textbackslash multicolumn} -\ST is compatible with the syntax \verbinline=\multicolumn{}{}{}= which merges \falseverb{} cells in a unique cell whose type and content are specified in the arguments. - -Even when using \verbinline=\multicolumn=, \ST maintains some consistency in the references. In this table where \verbinline-\multicolumn- is used, the absolute references are displayed:\par\nobreak -\begin{center} -\ttfamily -\begin{tabular}{|*7{c|}}\hline -a1&b1&c1&d1&e1&f1&g1\\\hline -a2&\multicolumn{2}{l|}{b2}&d2&e2&f2&g2\\\hline -\multicolumn{3}{|l|}{a3}&d3&\multicolumn{2}{l|}{e3}&g3\\\hline -\end{tabular} -\end{center} -Thus, whatever the number of merged cells, the next cell has a column number that takes into account the number of merged cells.\medskip - -In the last line, cells \falseverb{a3}, \falseverb{b3} and \falseverb{c3} are merged and consequently, the cells \falseverb{b3} and \falseverb{c3} \emph{do not exist} for \ST: it is not possible to refer to \falseverb{b3} or \falseverb{c3} anywhere in the table.\medskip - -In this example, every number in the top line is the product of the 2 numbers below:\par\nobreak -\begin{lstlisting} -\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} -\begin{spreadtab}{{tabular}{*6{K{0.5}}}} -\cline{2-5} -&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline -\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} -\begin{spreadtab}{{tabular}{*6{K{0.5}}}} -\cline{2-5} -&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline -\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline -\end{spreadtab} -\end{center} -The marker `\falseverb{:=}' is necessary in every cell where the command \verbinline-\multicolumn- is written. Without it, \ST would consider that the whole cell (i.e. \verb-\multicolumn{2}{|c|}{}-) as the formula, which is impossible to calculate. - -\section{Macro-functions} -The \falseverb{fp} package provides a limited set of operations and functions. If these are not sufficient then \ST allows the advanced programmer to write macros using the operations and functions of \falseverb{fp}. This section presents the macro-functions currently available\footnote{Many others should be written soon and be available in future versions of the package.}. There will be more details on how to program macro functions in the next version of this manual. - -\subsection{Mathematical macro-functions} -\subsubsection{Sum cells} -The macro-function \verbinline=sum= sums one or several ranges of cells. - -It should be used like this: \verbinline=sum(;;...;)=, where a range of cells is: -\begin{itemize} - \item either a single cell like \falseverb{a1} or \falseverb{[2,1]}; - \item or a rectangular area bounded by the upper-left cell and lower-right with this syntax:\par{\centering\verb=:=\par} - Here are some examples of such areas: \falseverb{a2:d5}, \falseverb{[-1,-1]:[2,3]}, \falseverb{b4:[5,1]}. -\end{itemize} -In cell ranges, if a cell does not have a numeric field (empty cell or text cell or merged cell with \verbinline-\mutlicolumn-), it is seen as 0 by \verbinline-sum-. - -In the following table, the sum of the binomial coefficients of Pascal's triangle is calculated:\par\nobreak -\begin{minipage}{0.75\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*5c}} -\multicolumn{5}{c}{sum: :={sum(a2:e6)}}\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1] & & & \\ -1 & & & & -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.25\linewidth} -\centering -\begin{spreadtab}{{tabular}{*5c}} -\multicolumn{5}{c}{sum: :={sum(a2:e6)}}\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1] & & & \\ -1 & & & & -\end{spreadtab} -\end{minipage}% - -\subsubsection{The \texttt{fact} macro} -The macro-function \verbinline=fact()= computes the factorial of its argument, assuming it is an \emph{integer} between 0 and 18 to avoid overflows\footnote{Indeed, for \falseverb{fp} the greatest integer is $10^{18}-1$. The factorial of 19 is greater than this.}. The \falseverb{} can also be a reference to a cell whose numeric field contains an integer.\medskip - -Here are the factorials from 0 to 8:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*9c}} - 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline -fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{*9c}} - 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline -fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) -\end{spreadtab} -\end{center} - -\subsubsection{The \texttt{sumprod} macro} -The function \verbinline=sumprod= multiplies the corresponding elements of 2 or more rectangular ranges and then adds these products. - -It should be used like this: \verbinline{sumprod(;;...;)}. All the ranges must have the same dimensions. - -In this simple example, the average age of a group of children aged from 10 to 15 years old is calculated:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{r*6c}} -@\Ages & 10 & 11 & 12 & 13 & 14 & 15\\ -@Number & 5 & 8 & 20 & 55 & 9 & 3\\\hline -@Average&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{r*6c}} -@Ages & 10 & 11 & 12 & 13 & 14 & 15\\ -@Number & 5 & 8 & 20 & 55 & 9 & 3\\\hline -@Average&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} -\end{spreadtab} -\end{center} -If any cell in the ranges is empty, pure text or merged with \verbinline-\multicolumn-, its numeric field is replaced by 0. - -\subsubsection{Random numbers} -The macro-functions \verbinline-randint- and \verbinline-rand- each returns a random number depending on its argument. - -It should be noted that the seed initializing the random sequence depends on the date and the minute at which the compilation is done. Thus, the random sequence of numbers given by this function will change between two compilations made at different times. If random numbers need to be repeatable, the private macro \verb-\ST@seed- must be cancelled and a seed should be chosen for \falseverb{fp}. Here is the code to do this:\par\nobreak -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\makeatletter -\renewcommand\ST@seed{}% redefines the private macro -\makeatother -\FPseed=27% gives a seed (any integer) to fp. -\end{lstlisting} -The macro-function \verbinline-randint([,])- returns a random \emph{integer} depending on its arguments: \verb== is an optional integer with default value 0. The random integer returned is in the interval \verb=[;=\linebreak[2]\verb=]=. - -The macro-function \verbinline-rand()- returns a random number between 0 and 1.\par\nobreak -\begin{lstlisting} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|cccc|}}\hline -@numbers in [0;1] &rand() &rand() &rand() &rand() \\ -@numbers in [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ -@numbers in [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ -\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|cccc|}}\hline -@numbers in [0;1] &rand() &rand() &rand() &rand() \\ -@numbers in [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ -@numbers in [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ -\hline -\end{spreadtab} -\end{center} - -\subsubsection{GCD and LCM} -The macro functions `gcd' and `lcm' compute the Greatest Common Divisor and the Least Common Multiple of the list of numbers in their argument: -\begin{center} -\verbinline-gcd(number1,number2,...,numberN)-\par -\verbinline-lcm(number1,number2,...,numberN)- -\end{center} -Example : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline -\multicolumn3{|c||}{@Numbers}& @GCD & @LCM \\\hline -24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ -15 & 10 & 25 & & \\ -16 & 12 & 15 & & \\ -\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline -\multicolumn3{|c||}{@Numbers}& @GCD & @LCM \\\hline -24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ -15 & 10 & 25 & & \\ -16 & 12 & 15 & & \\ -\hline -\end{spreadtab} -\end{center} - -\subsubsection{Scientific notation} -The macro function `scitodec' converts a number written in scientific notation into a decimal number, understandable by \ST to achieve its calculations. The syntax is \verbinline-scitodec()-, where \verb-- is: -\begin{itemize} - \item a sequence of characters with the syntax \verb-EE- where \verb-- is a decimal number and the \verb-- is an integer. The `EE' may be written uppercase or lowercase. - - \verb-EE- means the number $\text{\ttfamily }\times10^{\text{\ttfamily }}$ - \item a reference to the \emph{textual} field of a cell containing \verb-EE- -\end{itemize} -Example : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|r|}}\hline -@Scientific notations & @Decimal notations \\\hline -@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ -@-3.1EE-3 & \\ -@15ee5 & \\ -@-0.025ee7 & \\ -@2.125EE0 & \\ -@3.1575EE-4 & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|r|}}\hline -@Scientific notations & @Decimal notations \\\hline -@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ -@-3.1EE-3 & \\ -@15ee5 & \\ -@-0.025ee7 & \\ -@2.125EE0 & \\ -@3.1575EE-4 & \\\hline -\end{spreadtab} -\end{center} - -\subsubsection{Identity} -The simplest macro function is `\verbinline=id()='. It returns the number in its argument. Mathematically, it is not very useful, but with \ST, it makes possible the writing of mathematical expressions in arguments of macro functions where they are not otherwise allowed -- in the argument of \verbinline=sum= for example. - -In the code below, the \verbinline-id- macro function is used to compute the range of cells to add with \verbinline-sum-. In this example, the numeric field of the cell `a2' contains 8. Therefore, `\verbinline=sum([0,-1]:[id(a2-1),-1])/a2=' is equivalent to \verbinline=sum([0,-1]:[7,-1])/8=: - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{r*{10}c}} - @Integers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ -Mean of the :={8} first integers & sum([0,-1]:[id(a2-1),-1])/a2 \\ -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{r*{10}c}} - @Integers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ -Mean of the :={8} first integers & sum([0,-1]:[id(a2-1),-1])/a2 \\ -\end{spreadtab} -\end{center} - -\subsection{Tests} -Three macro-functions provide tests:\par\nobreak -\begin{center} -\verbinline=ifeq(number1,number2,number3,number4)=\par -\verbinline=ifgt(number1,number2,number3,number4)=\par -\verbinline=iflt(number1,number2,number3,number4)= -\end{center} -\falseverb{number1} and \falseverb{number2} are compared: -\begin{itemize} - \item for \verbinline-ifeq-, is \falseverb{number1} = \falseverb{number2}? - \item for \verbinline-ifgt-, is \falseverb{number1} > \falseverb{number2}? - \item for \verbinline-iflt-, is \falseverb{number1} < \falseverb{number2}? -\end{itemize} -If the test is positive, \falseverb{number3} is returned, otherwise it is \falseverb{number4}. - -Here are some values of the function -$f(x)=\begin{cases} -10 &\text{if }x<1\\ -0 &\text{if }x=1\\ --10 &\text{if }x>1 -\end{cases} -$\smallskip - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*2c|}}\hline -@$x$ & @$f(x)$ \\\hline --0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*2c|}}\hline -@$x$ & @$f(x)$ \\\hline --0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline -\end{spreadtab} -\end{center} - -\subsection{Macro-functions manipulating dates} -\subsubsection{Date to number with \ttfamily engshortdatetonum}\label{datetonum} -The macro \verbinline-engshortdatetonum- converts a short date like 1789/7/14 to an integer which is the number of days passed since the 1st March of the year 0\footnote{This year 0 does not exist but this should not be a problem with recent dates.}. It is important to note that this macro-function requires a \emph{textual} argument and not a number or the result of a mathematical calculation. Therefore, if the argument of this macro-function refers to a cell, that cell \emph{must} be a text cell, i.e. a cell containing `\verb-@-' or `\verb-:={}-'. - -In the example below, the first two lines show how to refer to a text cell. The third line displays the date 0 on the left, and more interesting on the right, it shows how to calculate the number corresponding to the current date with the use of the \TeX{} counters \verbinline-\year-, \verbinline-\month- and \verbinline-\day- which contain the numbers of the current year, month and day.\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{cc}} -@1789/7/14 & engshortdatetonum(a1)\\ -2001/1/1 :={} & engshortdatetonum(a2)\\\hline -engshortdatetonum(0/3/1) & engshortdatetonum(\number\year/\number\month/\number\day) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{cc}} -@1789/7/14 & engshortdatetonum(a1)\\ -2001/1/1 :={} & engshortdatetonum(a2)\\\hline -engshortdatetonum(0/3/1) & engshortdatetonum(\number\year/\number\month/\number\day) -\end{spreadtab} -\end{center} -Another macro-function provides the same feature but with a long date like `December 25, 1789' or the string contained in \verbinline-\today-:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{cc}} -englongdatetonum(February 13, 2005) & englongdatetonum(\today)\\ -@July 1, 1970 & englongdatetonum(a2) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{cc}} -englongdatetonum(February 13, 2005) & englongdatetonum(\today)\\ -@July 1, 1970 & englongdatetonum(a2) -\end{spreadtab} -\end{center} - -\subsubsection{From a number to a date} -Several macro-functions translate a number into a date. All these macro-functions have in common that their result is \emph{text}. Therefore, the cells containing such results \emph{become cells containing text} and if the cell is composed of two fields, the numeric field becomes empty and `\verb-:={}-' is replaced by its result in the text field. - -These macro-functions are: -\begin{itemize} - \item \verbinline-numtoengshortdate- translate a number into a short date like `1789/7/14'; - \item \verbinline-numtoenglongdate- translate a number into a long date like `July 14, 1789'; - \item \verbinline-numtoengmonth- given a number representing a date, it finds the name of the month; - \item \verbinline-numtoengday- same as above but it finds the name of the day. -\end{itemize} -Here is an example in which we consider 1000 days before and 1000 days after 2009/6/1. For each of these 2 dates, we calculate the short date, long date, month and day of the week.\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{cc}} \hline -\multicolumn{2}{|c|}{@2009/6/1} \\\hline\hline -1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ -1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ -1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ -1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) \\\hline --1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ --1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ --1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ --1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{cc}} \hline -\multicolumn{2}{|c|}{@2009/6/1} \\\hline\hline -1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ -1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ -1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ -1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) \\\hline --1000 & numtoengshortdate(engshortdatetonum(a1)+[-1,0])\\ --1000 & numtoenglongdate(engshortdatetonum(a1)+[-1,0]) \\ --1000 & numtoengmonth(engshortdatetonum(a1)+[-1,0]) \\ --1000 & numtoengday(engshortdatetonum(a1)+[-1,0]) -\end{spreadtab} -\end{center} - -\subsection{Coordinate macro functions}\label{tag} -Rather than referring to a cell by its coordinates which are difficult to remember and change if you insert a row or column, it is sometimes more convenient to give a name to a cell and refer to it later by name. - -The macro function `\verbinline-tag()-' gives a name to the cell in which it is located. This is not really a macro function like the others, since it returns nothing when put in a formula and disappears without causing any effect on the mathematical result. We can write `\verbinline-tag()-' \emph{anywhere} in the numeric field of a cell. The \verb-- can be any string of alphanumeric characters, but it is not advisable to put a letter and a number that could be understood as a reference to a cell, and would therefore be modified at a copy operation with \verbinline-\STcopy-. This macro function has an additional action, it saves via a \verbinline-\def- the numeric value of the cell in which it is located in order to be able to use later \emph{outside} the table via the purely expandable command \verbinline-\STtag{}-. - -Later in the table, instead of writing the coordinates of the cell, we can write `\verbinline-cell()-', which is a macro function that returns the coordinates of the cell named \verb--. For example, if `\verbinline-tag()-' is written in the cell `\verb-B3-' and in a further cell, we write `\verbinline-cell()-', this macro function returns \verb-B3-. - -Here is an example where we add cells and the name `\verb-foo-' is given to the first number and the name `\verb-bar-' to the last. One can see that \verbinline-tag(foo)- is between `1' and `9' but at the end, since this macro function diappears, the numeric field of the cell will be `19': -\begin{lstlisting} -\begin{spreadtab}{{tabular}{r@{}r}} - & 15tag(foo) \\ -@+ & 37 \\ -@+ & 13 \\ -@+ & 48 \\ -@+ & 1tag(bar)9 \\\cline{2-2} - & sum(cell(foo):cell(bar))tag(baz) -\end{spreadtab} - -foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{r@{}r}} - & 15tag(foo) \\ -@+ & 37 \\ -@+ & 13 \\ -@+ & 48 \\ -@+ & 1tag(bar)9 \\\cline{2-2} - & sum(cell(foo):cell(bar))tag(baz) -\end{spreadtab} - -foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} -\end{center} -When the environment \ST is nested in another environment, the assignments made by the macro funtion \verbinline-tag- are \emph{local} in this environment and could not be accessed outside of this environment via \verbinline-\STtag-. In the example below, the table made with \ST is in a \verbinline-center- environment and we must use \verbinline-\STmakegtag{}- to make global the previous saving of the numerical value contained in the cell marked by `tag()': - -\begin{minipage}{.6\linewidth} -\begin{lstlisting} -\begin{center} - \begin{spreadtab}{{tabular}{cccc}}\hline - 6&9&17&21\\\hline - \multicolumn{4}{c}{average = :={sum(a1:d1)/4tag(avg)}} - \end{spreadtab} - \STmakegtag{avg} -\end{center} -The average is \STtag{avg}. -\end{lstlisting} -\end{minipage}\kern6pt -\begin{minipage}{.3\linewidth} -\begin{center} - \begin{spreadtab}{{tabular}{cccc}}\hline - 6&9&17&21\\\hline - \multicolumn{4}{c}{average = :={sum(a1:d1)/4tag(avg)}} - \end{spreadtab} - \STmakegtag{avg} -\end{center} -The average is \STtag{avg}. -\end{minipage} - -The argument of \verbinline-\STmakegtag- can be made of several names, separated with commas. - -Although at first sight less useful, \ST also provides the macro functions `\verbinline-row()-' and `\verbinline-col()-' that return the number of the row or column of the cell \verbinline-tag()-. Here is an example of how to calculate the average of a number of values; the first and last values are tagged `first' and `last' and therefore, the number of values is row(last)-row(first)+1: - -\begin{minipage}{0.6\linewidth} -\begin{lstlisting} -average = \begin{spreadtab}{{tabular}[b]{r}} -7tag(first)\\9\\15\\6\\20\\13\\11\\55tag(last)\\ -\hline -sum(cell(first):cell(last))/(row(last)-row(first)+1) -\end{spreadtab} -\end{lstlisting} -\end{minipage}\hfill -\begin{minipage}{0.35\linewidth} -average = \begin{spreadtab}{{tabular}[b]{r}} -7tag(first)\\9\\15\\6\\20\\13\\11\\55tag(last)\\ -\hline -sum(cell(first):cell(last))/(row(last)-row(first)+1) -\end{spreadtab} -\end{minipage} - -\section{Particular care} -\subsection{Defining new commands with \ttfamily\textbackslash hline} -It may be useful to define a new command to produce, for example, a double horizontal line:\par\nobreak -\begin{center} -\verbinline-\newcommand\dline{\hline\hline}- -\end{center} -and then try to use it in a table as in this simple example that computes the Fibonnacci sequence in the second line: -\begin{center} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{center} -But, if you write the following code, there is a problem when compiling:\par\nobreak -\begin{lstlisting} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -1 & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{lstlisting} -In the log file, you can read that \verb-\FPeval- fails and complains:\par -\hfill\falseverb{! Improper alphabetic constant.}\hfill\null - -The reason is simple, \verb-\dline- in line 4 is not recognized by \ST as a horizontal rule and therefore, \emph{it is placed in the cell in the next line}. For \ST, the cell \falseverb{b1} contains:\par -\hfill\falseverb{\dline 1}\hfill\null - -Since there is no \verb-@- or \verb-:={}-, \ST considers that the whole cell is a numeric field and \verb-\FPeval- tries valiantly to calculate this content and obviously fails. - -To compile without error, the cell \falseverb{a2} \emph{must} contain a numeric field marker:\par\nobreak -\begin{lstlisting} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{center} - -\subsection{The use of {\ttfamily\textbackslash multicolumn} and \ttfamily\textbackslash SThidecol} -Firstly, in normal use, joint use of \verbinline |\multicolumn| and \verbinline-\SThiderow- should not happen, and most users should not encounter this situation and should not read this section. - -For the brave here is the problem: first, a hidden column \emph{must not} contain a cell with the command \verbinline-\multicolumn-! But what happens if a hidden column hides cells merged with \verbinline-\multicolumn-? - -In general, there is no compilation error or error messages, but there are some subtleties about the references that are a bit turned upside down in the line after the \verbinline-\multicolumn- command\ldots - -Let's take an example, and let's say that, in the following table, we want to merge the cell \falseverb{b2} to \falseverb{h2} and we also want to hide the colomns \falseverb{c}, \falseverb{d} and \falseverb{f}, here in gray:\par\nobreak -\begin{center} -\ttfamily -\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|} -\hline - a1 & b1 & \cellcolor[gray]{0.6}c1 & \cellcolor[gray]{0.6}d1 & e1 & \cellcolor[gray]{0.6}f1 & g1 & h1 & i1 & j1\\\hline - a2 & \multicolumn1c{b2} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1c{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{c}{} & \multicolumn1{c|}{} & i2 & j2\\\hline -\end{tabular} -\end{center} -There are 4 visible merged cells, so we write \verbinline-\multicolumn{4}- because hidden columns are never taken into account when counting the number of \verbinline-\multicolumn-. - -Then we count 4 letters from \falseverb{b} (this letter included): we obtain the letter \falseverb{e}. In the range \falseverb{b-e}, let's count: 2 gray hidden columns are included (\falseverb c and \falseverb d) and 1 hidden column is not included (\falseverb f). These numbers are important to understand the following, also let's call them $x$ and $y$ in the general case. - -The rule is: -\begin{itemize} - \item it is necessary to add $y$ signs \verb-&- after \verbinline-\multicolumn- (in the example above, it would be 1); - \item references to columns of cells after the \verbinline-\multicolumn- will be shifted $x$ to the beginning of the alphabet. For the example given, if we want to refer to the cell \falseverb{i2}, we should write \falseverb{g2} instead of \falseverb{i2}. -\end{itemize} -Here is an example with a similar structure to the previous ($x=2$ and $y=1$) with simple formulas: add 1 to the number above.\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*{7}{c|}}} -\hline -1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline -a1+1& \multicolumn4{l|}{:={b1+1}} & & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*{7}{c|}}} -\hline -1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline -a1+1& \multicolumn4{l|}{:={b1+1}} & & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline -\end{spreadtab} -\end{center} -And another example with $x=1$ and $y=0$ where a single column is hidden \falseverb d:\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*{9}{c|}}} -\hline -1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline -a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*{9}{c|}}} -\hline -1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline -a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline -\end{spreadtab} -\end{center} - -\subsection{Messages delivered by \ST} -The package delivers error messages and aborts compilation in these cases: -\begin{itemize} - \item a circular reference is found in a cell. In this case, the dependent cells are displayed; - \item a cell refers to an empty cell or a text cell when a non-empty numeric field is expected; - \item a cell refers to an undefined cell (outside the table); - \item a cell refers to a cell merged by a \verbinline-\multicolumn- command; - \item a relative reference has bad syntax. -\end{itemize} -The package can deliver informative messages (in the log file), which it does by default. If the user wants or not the delivery of informative messages, the syntax is \verbinline-\STmessage{true}- or \verbinline-\STmessage{false}-. - -To understand the meaning of these messages, let's take a simple table:\par\nobreak -\begin{minipage}{0.65\linewidth} -\begin{lstlisting} -\STmessage{true}% already set by default -\begin{spreadtab}{{tabular}{|cccc|c|}}\hline -b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.35\linewidth} -\centering -\begin{spreadtab}{{tabular}{|cccc|c|}}\hline -b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline -\end{spreadtab} -\end{minipage} - -Here are the messages deliverd by \ST:\par\nobreak -\begin{lstlisting} -[spreadtab] New spreadtab {tabular}{|cccc|c|} -* reading tab: ok -* computing formulas: - cell A1-B1-C1 - cell B1 - cell C1 - cell D1 - cell E1 -* building tab: ok -[spreadtab] End of spreadtab -\end{lstlisting}\medskip -Preceded by a star, we recognize the 3 steps necessary for \ST to complete its task: reading the table, calculation of the formulas and building the final table. - -For the second step, cells are evaluated from top to bottom, left to right: at line 4 in the code above, \ST says that it begins by trying to calculate the first cell \falseverb{A1}. After a dash, we see that for this, it must first compute the cell \falseverb{B1}, which itself requires that the cell \falseverb{C1} is calculated: the latter can be calculated since it depends only on \falseverb{D1} which is a cell containing the number 10. - -In the following (lines 5 to 8), there is only one cell per line which means that when \ST tries to evaluate the cell, either it contains a number or dependent cells are already calculated. - -\subsection{Debug mode} -To ease the use of \ST, a debug mode is available. It is activated when the command \verbinline-\STdebug- is written in the optional argument of the \verbinline-spreadtab- environment. This command changes the behavior of \ST which, instead of displaying the final table, displays one (or more) table(s) containing debugging information. This display is done just after \ST has read all the cells, and no calculating of formulas has yet taken place. There are as many tables as commands \verbinline-\STdebug-, provided that their argument is different. Only 3 arguments are possible: -\begin{itemize} - \item \verbinline-\STdebug{formula}-: displays all the numeric fields and the ends of lines; - \item \verbinline-\STdebug{text}-: displays all the textual fields; - \item \verbinline-\STdebug{code}-: displays the internal code of the cells. Indeed, \ST assigns a code to every cell when it reads the table. Here are the possible values of this code: - \begin{enumerate}[label=\small\textbullet] - \item $-1$ if the cell is merged with \verbinline-\multicolumn-; - \item 0 if the cell is a text cell or is empty; - \item 1 if the numeric field of the cell contains a formula which will be computed later; - \item 2 if the numeric field of the cell contains a number. - \end{enumerate} -\end{itemize} - -When the `debug mode' is activated, the final table is not displayed. - -Here is a table which will be used for the next example: - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|r|r|}}\hline -@$x$ &@$y$ & @$x+y$\\\hline\hline -22 & 54 & \STcopy{v3}{a2+b2} \\ -43 & 65 & \\ -49 & 37 & \\\hline -$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline -\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|r|r|}}\hline -@$x$ &@$y$ & @$x+y$\\\hline\hline -22 & 54 & \STcopy{v3}{a2+b2} \\ -43 & 65 & \\ -49 & 37 & \\\hline -$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline -\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} -\end{spreadtab} -\end{center} -Let's ask \ST to show the 3 possible debugging tables for the table above. To do this, just change line 1 in the code above to: - -\hfill\verbinline[basicstyle=\ttfamily\small]-\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline-\hfill\kern0pt -\begin{center} -\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline -@$x$ &@$y$ & @$x+y$\\\hline\hline -22 & 54 & \STcopy{v3}{a2+b2} \\ -43 & 65 & \\ -49 & 37 & \\\hline -$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline -\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} -\end{spreadtab} -\end{center} -These 3 debugging tables may help to better understand what happens behind the scene when \ST works. We can observe that all cells with a numeric field (see table 2) have an internal code of 1 or 2 (see table 3) and an associated numeric field marker `\verb-:=-' in table 1. This marker represents the location where (by substitution) the result of the numeric field will be inserted. So from the contents of text fields in table 1 and, once calculated, the numeric fields, by a simple substitution, the cells are reconstituted to give those of the final table. - -In the debugging tables, cells containing the coordinates are grayed if the package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/colortbl/}{\texttt{\textbf{colortbl}}} has been loaded; they are left white otherwise. - -\section{Examples} -In the examples of this section, the numbers entered by the user are in \textcolor{black}{red} and the calculated numbers are in \textcolor{black}{black} - -In these tables, lots of tricks (struts, \verbinline-\multicolumn- commands) and packages (including the numprint package and its columns `N', which aligns the decimal points) were used to obtain a satisfactory result. The code is sometimes cumbersome and difficult to read, but these tables are not basic but well-groomed examples! - -\subsection{Pascal's triangle again!} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*7r}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ -[0,1] & [-1,1] & & & & & \\ -\color{red}:={1}& & & & & & -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{*7r}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ -[0,1] & [-1,1] & & & & & \\ -\color{red}:={1}& & & & & & -\end{spreadtab} -\end{center} - -\subsection{The convergence of a series} -For people familiar with maths, here is the series of the exponential. Indeed, -\[\forall x\in \mathbf{R}\qquad e^x=\sum_{k=0}^\infty\frac{x^k}{k!}\] -and this table shows the speed of convergence for $x=0.5$ -\begin{lstlisting} -\STautoround{15} -\renewcommand\STprintnum[1]{\numprint{#1}} -\begin{spreadtab}{{tabular}{cc}} -\multicolumn{2}{c}{Convergence at $x=\color{red}:={0.5}$}\\[1.5ex] -@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline -\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ -\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STautoround{15} -\renewcommand\STprintnum[1]{\numprint{#1}} -\begin{spreadtab}{{tabular}{cc}} -\multicolumn{2}{c}{Convergence at $x=\color{red}:={0.5}$}\\[1.5ex] -@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline -\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ -\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\\hline -\end{spreadtab} -\end{center} - -\subsection{Convergence to the golden ratio} -In mathematical terms, the sequence $F_n$ of Fibonacci numbers is defined by the recurrence relation:\[F_0=1\qquad F_1=1\qquad F_{n+2}=F_{n+1}+F_n\] - -The golden ratio is the limit of the ratios of successive terms of the Fibonacci sequence. We show here that the quotients $F_{n+1}/F_n$ approximate the golden ratio $\varphi=\frac{1+\sqrt{5}}{2}$ alternately lower and higher than $\varphi$.\par\nobreak -\begin{lstlisting} -\STautoround{9} -$\begin{spreadtab}{{array}{ccN39N{3}{9}}} -@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline -\color{red}:=1 & \color{red}:=1 & & \\ -\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ - & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\\hline -\end{spreadtab}$ -\end{lstlisting} -\begin{center} -\STautoround{9} -$\begin{spreadtab}{{array}{ccN39N{3}{9}}} -@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline -\color{red}:=1 & \color{red}:=1 & & \\ -\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ - & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\\hline -\end{spreadtab}$ -\end{center} - -\subsection{A billing table} -Here is a billing table where the decimal points are aligned in columns with the column specifier `N' of the package \falseverb{numprint}. - -This table is generated by the environment \verb=tabularx= stretched to fit 80\% of the width of the line. The command \verbinline=\multicolumn= has been widely used for formatting:\par\nobreak -\begin{lstlisting} -\nprounddigits2 -\let\PC\% -\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} -\newcommand\RED{\color{red}} -\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} -\hline -@Item &@\multicolumn1c{Price/U}& @\multicolumn1c{Qty} & @\multicolumn1c{Price} & @\multicolumn1c{Reduction} & @\textbf{Net}\\\hline -@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline -@\multicolumn6c{}\\[-1.5ex]\cline{4-6}% empty line and raise it a little -@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ -\cline{4-6} -\end{spreadtab} -\end{lstlisting} -\begin{center} -\nprounddigits2 -\let\PC\% -\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} -\newcommand\RED{\color{red}} -\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} -\hline -@Item &@\multicolumn1c{Price/U}& @\multicolumn1c{Qty} & @\multicolumn1c{Price} & @\multicolumn1c{Reduction} & @\textbf{Net}\\\hline -@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline -@\multicolumn6c{}\\[-1.5ex]\cline{4-6}% empty line and raise it a little -@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ -\cline{4-6} -\end{spreadtab} -\end{center} - -\subsection{A magic square} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} -\hline -\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline -2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline -4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} -\hline -\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline -2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline -4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline -\end{spreadtab} -\end{center} - -\subsection{A pyramid of additions} -Each number is the sum of two numbers located below it. -\begin{lstlisting} -\newlength\cellsize -\setlength\cellsize{1.5cm} -\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} -\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} -\cline{4-5} -&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} -&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} -&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline -\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\newlength\cellsize -\setlength\cellsize{1.5cm} -\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} -\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} -\cline{4-5} -&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} -&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} -&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline -\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline -\end{spreadtab} -\end{center} -\medskip -\parskip0pt -\begin{center} -$\star$\par -$\star\quad\star$ -\end{center}\bigskip -That's all. I hope you will find this package useful!\par\nobreak\medskip - -I thank you in advance for sending by \href{mailto:unbonpetit@openmailbox.org}{\texttt{\textbf{email}}} any bug you find, any macro-function or improvment you would like to be implemented, assuming that it must be \emph{realistic}. This package has to be modest and \ST is not excel or calc: it is impossible to implement some advanced features of these spreadsheets.\ldots\par\nobreak\bigskip -Christian \textsc{Tellechea} -\end{document} \ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.pdf b/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.pdf deleted file mode 100644 index 86e0ed3179f..00000000000 Binary files a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.tex b/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.tex deleted file mode 100644 index 698c1a88fd9..00000000000 --- a/Master/texmf-dist/doc/latex/spreadtab/spreadtab_doc_fr.tex +++ /dev/null @@ -1,1602 +0,0 @@ -% ____________________________________________________________________________ -% | | -% | | -% | spreadtab v0.4c | -% | | -% | 6 november 2014 | -% | | -% |___________________________________________________________________________| -% -% Ce fichier est spreadtab_doc_fr.tex, le code source de la documentation en -% français du package spreadtab. -% -% Copyright Christian Tellechea 2009-2014 -% email : unbonpetit@openmailbox.org -% -% ------------------------------------------------------------------- -% This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% -% http://www.latex-project.org/lppl.txt -% -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% ------------------------------------------------------------------- -\documentclass[a4paper,10pt]{article} -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} -\usepackage{libertine} -\renewcommand*\oldstylenums[1]{{\fontfamily{fxlj}\selectfont #1}} -\usepackage[scaled=0.8]{luximono} -\usepackage[a4paper,margin=2.6cm]{geometry} -\usepackage{amsmath,amssymb} -\usepackage{textcomp} -\usepackage{array} -\usepackage[table]{xcolor} -\usepackage{arydshln} -\usepackage{tabularx} -\usepackage{xcolor} -\usepackage{listings} -\usepackage{numprint} -\usepackage{xspace} -\usepackage[bottom]{footmisc} -\usepackage{spreadtab} -\usepackage[protrusion=true,final,verbose=true,babel=true]{microtype} -\usepackage{fancyhdr} - \fancyhead[L]{} - \fancyhead[C]{\small\bfseries\ST} - \fancyhead[R]{\scriptsize\slshape \leftmark} - \fancyfoot[l]{\tiny Compilé par Christian \textsc{Tellechea}, le \today.} - \fancyfoot[c]{} - \fancyfoot[r]{\thepage} -\usepackage[frenchb]{babel} -\frenchbsetup{StandardLists=true} -\usepackage{enumitem} -\makeatletter -\definecolor{ST@bckgcolor}{rgb}{0.87,0.9,1} -\definecolor{ST@codebckgcolor}{rgb}{0.9,0.9,0.9} -\definecolor{ST@keywordstc}{rgb}{0.7,0,0} -\definecolor{ST@keywordslatex}{rgb}{0,0,1} -\definecolor{ST@arguments}{rgb}{0,0,0} -\definecolor{ST@comments}{rgb}{0.5,0.5,0.5} -\lstset{% - language=[AlLaTeX]TeX,float=hbp,basicstyle=\footnotesize\ttfamily,identifierstyle=\color{ST@arguments},% - keywordstyle=\color{ST@keywordslatex},commentstyle=\itshape\color{ST@comments},% - columns=fixed,tabsize=4,frame=single,extendedchars=false,% - showspaces=false,showstringspaces=false,numbers=left,numberstyle=\tiny\ttfamily,% - breaklines=true,breakindent=3em,backgroundcolor=\color{ST@bckgcolor},breakautoindent=true,% - captionpos=t,xleftmargin=1em,xrightmargin=1em,lineskip=0pt,% - numbersep=1em,classoffset=1,% - morekeywords={% les macros et commandes de spreadtab - spreadtab,endspreadtab,SThiderow,SThidecol,STsavecell,STautoround,STmessage,STsetdecimalsep,STtransposecar,STdebug,STdisplaytab,STsetdisplaymarks,% - STnumericfieldmarker,STprintnum,STtextcell,STcopy,STtag,STmakegtag,STeol,fact,id,ifeq,ifgt,iflt,numtofrshortdate,% - numtoengshortdate,numtofrlongdate,numtoenglongdate,numtofrmonth,% - numtoengmonth,numtofrday,numtoengday,sum,rand,randint,sumprod,% - frshortdatetonum,engshortdatetonum,englongdatetonum,frlongdatetonum,gcd,lcm,tag,cell,row,col},% - keywordstyle=\color{ST@keywordstc},classoffset=0} - -%%%%%%%%%%% environnement OOcalc -\newcount\cntlin -\newcount\cntcol - -\newtoks\t@b -\long\def\ifremain@lines#1\\#2\@nil{% - \csname @\ifx\@empty#2\@empty second\else first\fi oftwo\endcsname} -\long\def\subst@eol#1\\#2\@nil{\addtot@b{#1\\\cline{1-1}\hdashline}% - \ifremain@lines#2\\\@nil{\addtot@b&\subst@eol#2\@nil}{\addtot@b{#2\end{tabular}}}} -\long\def\collect@body#1\end{\subst@eol#1\@nil\end} - -\newcommand\addtot@b[1]{\t@b\expandafter{\the\t@b#1}} -\newcommand\edftot@b[1]{\edef\temp@{#1}\expandafter\addtot@b\expandafter{\temp@}} - -\newenvironment{OOocalc}[2][1.5cm]{% #1=largeur colonnes #2 = nombre de colonnes - \newcolumntype w{>{\centering\arraybackslash}m{#1}}% - \arrayrulewidth0.4pt\dashlinedash0.4pt\relax\dashlinegap3pt - \global\cntlin\m@ne\global\cntcol\z@ - \tabfont - \tabcolsep0pt - \t@b{\begin{tabular}{% - |>{\cellcolor{tabheadcolor}% - \global\cntcol\z@\global\advance\cntlin\@ne - \centering\arraybackslash - \ifnum\cntlin>\z@\tableheadformat\number\cntlin\fi} - m{2em}|*{#2}{w:}}% - \hline - \rowcolor{tabheadcolor}}% - \loop - \ifnum\cntcol<#2 - \advance\cntcol\@ne - \addtot@b{&\multicolumn{1}{>\centering m{#1}|}}% - \edftot@b{{\noexpand\tableheadformat\@Alph\cntcol}}% - \repeat - \addtot@b{\\\hline&}% - \collect@body}{\the\t@b} -\makeatother - -% commandes de personnalisation de OOcalc -\newcommand*\tabfont{\fontfamily{phv}\selectfont\footnotesize}% police du tableau (helvetica ici) -\newcommand*\tableheadformat{\bfseries}% police des en-têtes du tableau (en gras) -\colorlet{tabheadcolor}{gray!40}% couleur de font des en-têtes du tableau -\colorlet{palepink}{pink!80} -\colorlet{lightpink}{pink!30} -\colorlet{palegreen}{green!60} -\colorlet{lightgreen}{green!30} -\newcommand\CC[1]{\cellcolor{#1}} - -\newcommand\verbinline[1][]{\lstinline[breaklines=false,basicstyle=\normalsize\ttfamily,#1]} -\newcommand\ST{\textsf{spreadtab}\xspace} -\newcommand\falseverb[1]{\texttt{\detokenize{#1}}} - -\usepackage[bookmarks=true,bookmarksopen=true,colorlinks=true,hyperfootnotes=false,filecolor=black,linkcolor=blue,urlcolor=magenta,pdfauthor={Christian TELLECHEA},pdftitle={spreadtab},pdfsubject={Spreadtab permet d'utiliser des fonctionnalités de tableur dans un tableau avec LaTeX},pdfkeywords={spreadtab},pdfcreator={LaTeX}]{hyperref} - -\begin{document} -\parindent0pt\pagestyle{fancy}\setitemize{leftmargin=3em,topsep=0pt,parsep=0pt,itemsep=0pt,label=--}\STsetdecimalsep{,} -\begin{titlepage} - \null\par\vfill - \begin{center} - \begin{minipage}{0.75\linewidth} - \begin{center} - \Huge\bfseries\ST\par\vspace{5pt} - \small v\csname ST@ver\endcsname\par\vspace{35pt} - \normalsize Manuel de l'utilisateur - \end{center} - \end{minipage} - \end{center} - \vspace{1cm} - \begin{center} - Christian {\sc Tellechea}\par\small - \href{mailto:unbonpetit@openmailbox.org}{\texttt{\textbf{unbonpetit@openmailbox.org}}}\par\vspace{5pt} - \csname ST@fr@date\endcsname - \end{center} - \vfill - \begin{center} - \begin{minipage}{0.8\linewidth} - \noindent\hrulefill\par - \hfill\textbf{\textit{Résumé}}\hfill{}\medskip\par\footnotesize - Cette extension permet d'utiliser des fonctionnalités de tableur dans n'importe quel environnement \og tableau\fg{} avec \LaTeX{}.\par\smallskip - La principale fonctionnalité étant de pouvoir écrire des formules dans les cellules d'un tableau qui font références à d'autres cellules, de calculer les formules contenues dans les cellules et d'afficher les résultats numériques de ces formules dans le tableau.\par - \hrulefill - \end{minipage} - \end{center} - \vfill{} -\end{titlepage} - -\tableofcontents\newpage -\parskip\medskipamount -\section{Introduction} - -\subsection{Présentation} -Cette extension permet de construire des tableaux similaire à des feuilles de calculs. Les cellules du tableau ont des coordonnées (colonne et ligne) qui peuvent être utilisées dans des formules pour calculer des valeurs dans d'autres cellules. - -Ce package nécessite le moteur $\varepsilon$-\TeX, le format \LaTeXe{} ainsi que le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} à qui sont confiés les calculs. Le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/xstring/}{\texttt{\textbf{xstring}}} est également requis dans une version \emph{supérieure ou égale} à la version \verb-v1.5d [2010/03/28]-. - -J'ai souhaité dès le départ de rendre ce package compatible avec \emph{tous} les environnements de tableaux, sous réserve que les séparateurs entre colonnes soient \og\verb=&=\fg{} et les retours à la ligne soient \og\verb=\\=\fg{}. Cette contrainte forte sur la compatibilité m'a conduit à programmer \ST pour qu'il agisse d'une façon \emph{totalement indépendante} de l'environnement tableau. Ainsi, la lecture du tableau, le traitement et le calcul des formules se fait \emph{avant} que l'environnement tableau ne prenne la main et ne \og voit\fg{} le corps du tableau. - -Par conséquent, \ST procède en 3 étapes : -\begin{itemize} - \item en premier lieu, \ST lit le corps du tableau et le divise en lignes puis en cellules en reconnaissant dans chacune la présence d'une éventuelle formule; - \item ensuite, il procède au calcul des formules contenues dans les cellules, en ayant pris soin pour chacune de calculer auparavant les cellules dépendantes. L'ordre dans lequel les cellules doivent être calculées est déterminé par \ST. Les calculs sont faits par le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}}; - \item enfin, il faut reconstruire le tableau en ayant remplacé chaque formule par la valeur numérique préalablement calculée et passer la main à l'environnement tableau spécifié par l'utilisateur. -\end{itemize} -Les deux syntaxes possibles (et équivalentes) sont les suivantes, où \verb-- représente le nom de n'importe quel environnement de type tableau disponible avec \LaTeX{} ou avec une extension :\par\nobreak -\begin{minipage}{0.48\linewidth} -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\begin{spreadtab}{{}{}} - tableau avec formules et nombres -\end{spreadtab} -\end{lstlisting} -\end{minipage}\hfill ou\hfill -\begin{minipage}{0.48\linewidth} -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\spreadtab{{}{}} - tableau avec formules et nombres -\endspreadtab -\end{lstlisting} -\end{minipage} - -et après le travail de \ST, on obtient un affichage comme si l'on avait écrit :\par\nobreak -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\begin{}{} - tableau avec nombres -\end{} -\end{lstlisting} - -Même si disposer de fonctionnalités ressemblant à celles d'un tableur avec \LaTeX{} est appréciable, il ne faut pas perdre de vue que les 3 étapes décrites ci-dessus prennent du temps et surtout que \falseverb{fp} est lent dans ses calculs. L'ensemble conduit donc à des temps de compilation \emph{beaucoup plus importants} qu'avec un tableau classique. - -Il faut ajouter que \ST \emph{ne peut remplacer un tableur}. En effet, ses possibilités sont très limitées. De plus, surtout pour des tableaux complexes ou de grande taille, le manque d'aide visuelle devient gênant\footnote{Ceci dit, je certifie qu'avec l'habitude, cette gêne tend à s'estomper (si l'on s'en tient à des tableaux raisonnables, bien sûr).}, et la syntaxe de \ST constitue aussi un obstacle supplémentaire. L'avantage de cette extension est de pouvoir écrire \emph{dans le code \LaTeX} des tableaux comportant des calculs, alors que ces tableaux sont généralement exportés\footnote{On peut signaler les 2 principaux programmes d'exportation : \href{http://calc2latex.sourceforge.net/}{\texttt{\textbf{cacl2latex}}} pour \og calc\fg{} de Open Office, et \href{http://www.ctan.org/tex-archive/support/excel2latex/}{\texttt{\textbf{excel2latex}}} pour \og excel\fg{} de Microsoft Office.} d'une feuille de calcul d'un tableur vers le code \LaTeX. On évite ainsi les désagréments des programmes d'exportation : mise en forme souvent à retoucher pour obtenir exactement ce que l'on veut, non compatibilité avec tous les environnements de tableaux, obtention de tableaux ne contenant que les valeurs (les formules sont perdues à l'exportation), exportation à recommencer si l'on modifie un seul nombre ou formule dans le tableau. - -\subsection{Motivation} -Quelques mois avant de commencer à m'attaquer à ce package, Derek \textsc{O'Connor} m'avait fait remarquer que rien n'était disponible dans le monde des extensions de \LaTeX{} pour imiter ---~ne serait-ce qu'un peu~--- le calcul de formules dans des tableaux, comme cela se fait couramment avec des tableurs. J'ai trouvé le défi intéressant et je me suis lancé dans l'écriture de ce package qui en fait, n'est qu'un exercice de programmation. - -La route a été longue avant d'arriver à cette version et je tiens à remercier tout particulièrement Christophe \textsc{Casseau} pour l'intérêt qu'il a porté dès le début à ce travail et les suggestions qu'il m'a faites, ainsi que plus récemment Derek \textsc{O'Connor} pour ses conseils et pour les échanges constructifs que nous avons eus. J'adresse également mes remerciements à Andrew \textsc{Parsloe} pour la relecture et les corrections apportées à la traduction de ce manuel en anglais. - -\section{Fonctionnalités courantes} -Il faut noter tout d'abord qu'à l'intérieur d'un tableau sous environnement \ST, les caractères \og\verb=:=\fg{} et \og\verb=;=\fg{} perdent leur code de catégorie actif qui leur a été attribué si vous utilisez l'option \falseverb{frenchb} du package \falseverb{babel}. Par conséquent, l'espace automatique inséré avant ces caractères sera désactivé dans un tableau. - -\label{STeol}Par défaut, \ST considère qu'une ligne se termine avec ``\verb-\\-'' qui est habituel dans les tableaux. Ce marqueur de fin de ligne peut être modifié via la commande \verbinline-\STeol{}-. On peut par exemple écrire \verbinline-\STeol{\tabularnewline}-. Il faut bien comprendre que les fins de lignes qui seront insérées dans le tableau final seront toujours ``\verb-\\-'', même si le marqueur de fin de ligne lorsque \ST \emph{lit} le tableau a été modifié. - -\subsection{Références absolues} -Dans le tableau, les cellules sont repérées par leur références absolues de cette façon : -\begin{itemize} - \item la colonne est une lettre de \falseverb a à \falseverb z, \falseverb a représentant la 1\iere{} colonne de gauche : on est donc d'emblée limité à 26 colonnes, ce qui devrait suffire pour la grande majorité des cas; la lettre est insensible à la casse, elle peut donc être indifféremment minuscule ou majuscule; - \item à la suite immédiate de la lettre, un nombre entier strictement positif représente le numéro de la ligne, la ligne numéro 1 étant la ligne du haut. -\end{itemize} -Une référence absolue s'écrit donc par exemple : \og\falseverb{b4}\fg{}, \og\falseverb{C1}\fg{} ou \og\falseverb{d13}\fg\footnote{Cette notation se retrouve dans les tableurs : la lettre représente la colonne et le nombre qui suit représente la ligne. Cet ordre est le contraire de la convention utilisée avec les matrices en mathématiques.}. Visuellement, on peut illustrer ce fonctionnement par ce genre de tableau ressemblant à un tableur, ici volontairement limité à 5 lignes et 5 colonnes : -\begin{center} -\begin{OOocalc}[6em]{5} -&&&&\\&&&&\\&&&&\\&&&&\\&&&&\\ -\end{OOocalc} -\end{center} -Voici un exemple où l'on calcule la somme de chaque ligne et de chaque colonne puis, la somme totale :\par\nobreak -\begin{minipage}{0.75\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{rr|r}} -22 & 54 & a1+b1 \\ -43 & 65 & a2+b2 \\ -49 & 37 & a3+b3 \\ -\hline -a1+a2+a3 & b1+b2+b3 & a4+b4 -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.25\linewidth} -\centering -\begin{spreadtab}{{tabular}{rr|r}} -22 & 54 & a1+b1 \\ -43 & 65 & a2+b2 \\ -49 & 37 & a3+b3 \\ -\hline -a1+a2+a3 & b1+b2+b3 & a4+b4 -\end{spreadtab} -\end{minipage}% - -Pour les matheux, voici un autre exemple où l'on calcule quelques lignes du triangle de Pascal :\par\nobreak -\begin{minipage}{0.75\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{ccccc}} -1 & & & & \\ -a1 & a1 & & & \\ -a2 & a2+b2 & b2 & & \\ -a3 & a3+b3 & b3+c3 & c3 & \\ -a2 & a4+b4 & b4+c4 & c4+d4 & d4 -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.25\linewidth} -\centering -\begin{spreadtab}{{tabular}{ccccc}} -1 & & & & \\ -a1 & a1 & & & \\ -a2 & a2+b2 & b2 & & \\ -a3 & a3+b3 & b3+c3 & c3 & \\ -a2 & a4+b4 & b4+c4 & c4+d4 & d4 -\end{spreadtab} -\end{minipage}% - -\subsection{Références relatives} -Pour faire référence à une cellule, il peut être commode de spécifier sa position par rapport à la cellule où se trouve la formule. Ainsi, les coordonnées \og relatives\fg{} d'une cellule sont 2 nombres relatifs écrits selon cette syntaxe : \falseverb{[x,y]}, où \falseverb x est le décalage horizontal par rapport à la cellule contenant la formule et \falseverb y est le décalage vertical. Ainsi, \falseverb{[-2,3]} fait référence à la cellule se trouvant 2 colonnes avant (à gauche) et 3 lignes après (plus bas) la cellule où se trouve la formule. - -Voici à nouveau le triangle de Pascal vu ci-dessus, mais les références sont relatives et l'environnement \og\verbinline-matrix-\fg{} du package \href{http://www.ctan.org/tex-archive/macros/latex/required/amslatex/math/}{\texttt{\textbf{amsmath}}} est utilisé :\par\nobreak -\begin{minipage}{0.82\linewidth} -\begin{lstlisting} -$ -\begin{spreadtab}{{matrix}{}} -1\\ -[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] -\end{spreadtab} -$ -\end{lstlisting} -\end{minipage}\hfill -\begin{minipage}{0.15\linewidth} -\centering -$ -\begin{spreadtab}{{matrix}{}} -1\\ -[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]\\ -[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1]+[0,-1] & [-1,-1] -\end{spreadtab} -$ -\end{minipage}% - -On remarque que les références relatives sont plus adaptées ici puisque seulement 2 références différentes sont utilisées : \falseverb{[0,-1]} qui se réfère à la cellule de dessus et \falseverb{[-1,-1]} qui se réfère à la cellule au Nord-Ouest de la cellule où se trouve la formule. - -On peut utiliser dans une même formule un mélange de références absolues et relatives. - -\subsection{Cellules de texte} -Si l'on veut mettre du texte dans une cellule, il faut indiquer à \ST que la cellule ne doit pas être calculée. Il suffit de placer quelque part dans la cellule le caractère \og\falseverb @\fg{}. Ce faisant, la cellule est ignorée par \ST et devient une cellule inerte à qui il n'est pas possible\footnote{Il y a une exception à cette règle, voir la page \protect\pageref{datetonum}.} de faire référence nulle part ailleurs dans le tableau. - -Voici un exemple :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ valeurs de $x$ & -5 & -1 & 4 \\ -@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ valeurs de $x$ & -5 & -1 & 4 \\ -@ $f(x)=2x$ & 2*[0,-1] & 2*[0,-1] & 2*[0,-1] \\\hline -\end{spreadtab} -\end{center} -Le caractère \og\falseverb @\fg{} est le développement de la séquence de contrôle \verbinline=\STtextcell=. On peut donc redéfinir cette séquence de contrôle en ce que l'on veut et par exemple, \verbinline-\renewcommand\STtextcell{`}- fera qu'une cellule contenant le caractère ``\verb=`='' sera comprise comme étant une cellule de texte. - -De plus, si une cellule est vide ou entièrement constituée d'espaces, alors \ST la considérera comme une cellule de texte. - -\subsection{Cellules mixtes} -En réalité, chaque cellule est composée de \emph{deux} champs. D'un côté le \emph{champ numérique} qui contient la formule et de l'autre le \emph{champ textuel} qui sera ignoré par \falseverb{fp} et n'entre pas en ligne de compte pour les calculs : -\begin{itemize} - \item dans une cellule, si rien n'est précisé, la totalité de la cellule est considérée comme étant le champ numérique, et le champ textuel est vide (c'était le cas pour toutes les cellules du tableau du triangle de Pascal vu précédemment); - \item si la cellule contient \og\falseverb{@}\fg{}, alors la totalité de la cellule est considérée comme étant le champ textuel. Le champ numérique est vide et inaccessible. - \item si la cellule contient \og\verb-:=-\fg, alors l'argument entre accolades qui suit est le champ numérique, et tout le reste est le champ textuel. La cellule a cette structure :\par\smallskip - \hfil\verb-:={champ numérique}-\hfil\null\par\smallskip - On peut changer ce marqueur en la séquence de contrôle \og\verb-\=-\fg{} par exemple, en redéfinissant la macro \verbinline-\STnumericfieldmarker- de cette façon :\par\smallskip{\centering - \verbinline-\renewcommand\STnumericfieldmarker{\=}-\par\smallskip} - Dans ce cas, le développement de \verb-\=- n'aurait strictement aucune importance et n'interviendrait pas dans le processus : pour \ST, il ne s'agit que d'un marqueur de début de formule qui est cherché et reconnu sans être développé. -\end{itemize} -Une fois le \og\verb-champ numérique-\fg{} calculé, lui seul et le marqueur \og\verb-:=-\fg{} seront remplacés par la valeur numérique calculée. - -Il faut noter que \og\verb-:={champ numérique}-\fg{} peut se trouver à l'intérieur d'accolades et ce quelque soit le niveau d'imbrication. Par exemple, dans une cellule, on peut écrire \verb-\textbf{:={a1+1}}-. Si le champ numérique de la cellule \falseverb{a1} est 5, alors la cellule contiendra au final \verb-\textbf{6}-. - -Pour fixer les idées, voici un exemple très simple :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -valeur 1 : :={50} & valeur 2 : :={29} & moyenne : \textbf{:={(a1+b1)/2}}\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -valeur 1 : :={50} & valeur 2 : :={29} & moyenne : \textbf{:={(a1+b1)/2}}\\\hline -\end{spreadtab} -\end{center} -À noter également que \og\verb-:={}-\fg{}, qui définit formule vide, a le même effet que \og\verb-@-\fg dans une cellule : celle-ci est comprise comme cellule de texte. Cependant, \og\verb-@-\fg et \og\verb-:={}-\fg{} \emph{ne sont pas équivalents} car une cellule textuelle contenant ce dernier peut recevoir une formule par copie (voir section suivante), ce qui est impossible avec \og\verb-@-\fg. - -\subsection{Copier des formules} -Pour éviter d'avoir à recopier des formules identiques dans des cellules voisines, \ST fournit l'instruction \verbinline-\STcopy-. - -Cette commande se place dans une cellule selon cette syntaxe : -\begin{center} -\verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formule}- -\end{center} -où $x$ et $y$ sont des nombres positifs qui représentent des décalages horizontaux et verticaux par rapport à la cellule où se trouve l'instruction. La cellule qui contient la commande et la cellule obtenue par ces décalages définissent une plage rectangulaire de cellules qui recevront la \verb--\footnote{La copie ne peut donc se faire que vers des cellules se trouvant à droite et plus bas que la cellule dans laquelle se trouve la commande.}. La commande \verbinline-\STcopy -\emph{ne doit pas} se trouver dans une cellule où un marqueur de champ numérique \og\verb-:=-\fg{} est présent. - -Voici comment se déroule la copie : elle se fait en partant de la cellule où se trouve l'instruction, la cellule source. Pour chaque cellule cible, toutes les références dans la formule sont incrémentées pour tenir compte du décalage entre la cellule cible et la cellule source. Ainsi par exemple, mettons que la cellule source contienne la formule \verb-a1+b2+c3-. Lorsque cette formule est copiée dans une cellule cible se trouvant 2 colonnes à droite et 5 lignes en dessous, cette formule deviendra : \verb-c6+d7+e8-. La formule peut également contenir des références relatives qui, puisqu'elle sont relatives, ne seront pas modifiées. - -En faisant précéder d'un \og\verb-!-\fg une coordonnée d'une référence, cette coordonnée reste inchangée lors de la copie. Reprenons l'exemple précédent avec la formule \verb-a!1+!b2+!c!3-. Si cette formule est copiée dans la cellule se trouvant 2 colonnes à droite et 5 lignes en dessous, alors, elle deviendra : \verb-c1+b7+c3-. Cette fonctionnalité est compatible avec des références relatives : mettons qu'une cellule contienne la formule \verb|[-1,!-1]+[!-1,1]+[!1,!2]| et que cette formule soit copiée vers la cellule se trouvant 2 colonnes à droite et 5 lignes en dessous. Alors, elle deviendra : \verb|[-1,-6]+[-3,1]+[-1,-3]|. - -Le caractère \og\verb-!-\fg est le développement de la séquence de contrôle \verbinline-\STtransposecar-. On peut donc modifier ce caractère en tout autre avec \verbinline-\renewcommand\STtransposecar-\verb-{}-. Le point d'exclamation, utilisé par défaut, garde son code de catégorie actif qui lui a été attribué par le package \verb-babel- chargé avec l'option \verb-frenchb-. - -Dans la syntaxe \verbinline-\STcopy{>-$x$\verbinline-,v-$y$\verbinline-}{formule}-, si le nombre $x$ est absent, la copie dans le sens horizontal se fait vers la droite jusqu'au bord droit du tableau. Si $y$ est absent, la copie dans le sens vertical se fait jusqu'en bas du tableau. - -Voici quelques exemples : -\begin{tabular}{cl}\hline -\verb-{>3,v1}- & copie vers les 3 colonnes à droite et 1 ligne en dessous\\ -\verb-{>3}- & copie vers les 3 cellules de droite\\ -\verb-{v1}- & copie vers la cellule de dessous\\ -\verb-{>}- & copie vers toutes les cellules situées à droite\\ -\verb-{v}- & copie vers toutes les cellules situées en dessous\\ -\verb-{v,>}- & copie vers le bas et vers la droite à partir de la cellule courante\\\hline -\end{tabular} - -On peut facilement générer la table de multiplication de 1 à 10 : - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} -\hline -@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline -1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ -\STcopy{v}{a2+1} & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|c|*{10}{c}|}} -\hline -@$\times$ & 1 & \STcopy{>}{b1+1} & & & & & & & & \\\hline -1 & \STcopy{>,v}{!a2*b!1} & & & & & & & & & \\ -\STcopy{v}{a2+1} & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\ - & & & & & & & & & & \\\hline -\end{spreadtab} -\end{center} - -Lors d'une copie de formule, si la cellule cible contient déjà un champ numérique non vide, celui-ci n'est pas écrasé et la copie ne se fait pas. - -Si des commandes \verbinline-\STcopy- se trouvant danns des plusieurs cellules départ ont une même cellule cible, la formule que cette dernière reçoit est celle correspondant à la dernière commande \verbinline-\STcopy- rencontrée lorsque le tableau est lu de haut en bas et de droite à gauche. Dans l'exemple visuel ci-dessous, le \verbinline-\STcopy- se trouvant dans la cellule rose \falseverb{B1} a son champ cible partiellement recouvert par celui du \verbinline-\STcopy- se trouvant dans la cellule verte \falseverb{C3}. En effet, cette dernière est rencontrée plus tard lors de la lecture du tableau : -\begin{center} -\begin{OOocalc}[2.3cm]{6} -1 &\CC{palepink}\ttfamily\textbackslash STcopy \{v,>\}\{!a1+1\} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} \\ -2 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} ~\par~ \\ -3 &\CC{lightpink} &\CC{palegreen}\ttfamily\textbackslash STcopy \{>2,v1\}\{!a3*10\}&\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink} \\ -4 &\CC{lightpink} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightgreen} &\CC{lightpink}~\par~ \\ -5 &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink} &\CC{lightpink}~\par~ \\ -\end{OOocalc} -\end{center} -Voici cet exemple repris ci-dessous pour mettre en évidence ces comportements. Dans cet exemple, la celule \verb-b5- qui est composée d'un champ numérique et la cellule \verb-c5- qui est mixte, leur champ numérique n'étant pas vide, il est conservé. -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 &\STcopy{v,>}{!a1+1} & & & & \\\hline -2 & & & & & \\\hline -3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline -4 & & & & & \\\hline -5 & -1 & a:={0}b & & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 &\STcopy{v,>}{!a1+1} & & & & \\\hline -2 & & & & & \\\hline -3 & & \STcopy{>2,v1}{!a3*10} & & & \\\hline -4 & & & & & \\\hline -5 & -1 & a:={0}b & & & \\\hline -\end{spreadtab} -\end{center} -Comme on l'a dit à la fin du chapitre précédent, on peut également copier une formule dans une cellule de texte contenant un champ numérique vide (c'est-à-dire une cellule contenant \og\verb-:={}-\fg). Dans ce cas, la formule est copiée à l'endroit où se trouve \og\verb-:={}-\fg. Par contre, dans une cellule de texte contenant \og\verb-@-\fg, la copie ne se fait pas et la cellule reste purement textuelle. - -Exemple : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 & 2 & 3 & 4 & 5 & 6 \\\hline -X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*6{c|}}}\hline -1 & 2 & 3 & 4 & 5 & 6 \\\hline -X\STcopy{>}{a1+1}Y & @XY & X:={}Y & \textbf{:={}} & & \\\hline -\end{spreadtab} -\end{center} - -\section{Mise en forme du tableau} -\subsection{Séparateur décimal} -Le package \verb-fp- renvoie ses résultats décimaux avec le point comme séparateur décimal. Il est possible de changer ce séparateur décimal de telle sorte que tout se passe comme si les résultats retournés par \verb-fp- en tenaient compte. L'instruction \verbinline-\STsetdecimalsep- permet de changer le séparateur décimal en n'importe quel caractère en utilisant la syntaxe : -\begin{center} -\verbinline-\STsetdecimalsep-\verb-{}- -\end{center} -Pour une utilisation en langue française, il faut donc inclure dans le préambule cette ligne : -\begin{center} -\verbinline-\STsetdecimalsep{,}- -\end{center} -Pour les champs numériques se trouvant en mode math, il faut noter que la virgule n'est pas neutre dans ce mode. En effet, elle est considérée comme une ponctuation ce qui explique qu'elle est suivie d'une espace. Pour neutraliser cet espace, on peut mettre cette virgule entre accolades comme on le voit dans ce code : - -\begin{minipage}{0.65\linewidth} -\begin{lstlisting}[escapechar=Z,backgroundcolor=\color{ST@codebckgcolor}] -3,14 n'est pas affichZéZ comme $3,14$.\par -3,14 est affichZéZ comme $3{,}14$ -\end{lstlisting} -\end{minipage}\hfill -\begin{minipage}{0.35\linewidth} -3,14 n'est pas affiché comme $3,14$.\par -3,14 est affiché comme $3{,}14$ -\end{minipage}% - -Lorsque des cellules sont en mode math, on peut\footnote{Il est cependant préférable d'utiliser le package \texttt{numprint} pour formatter les résultats. On peut aussi modifier le code mathématique de la virgule : \texttt{\textbackslash mathcode`,="013B\textbackslash relax}. Cette modification, réservée aux utilisateurs avertis, fait entrer la virgule dans la classe 0 des signes ordinaires alors qu'elle est naturellement dans la classe 6 des signes de ponctuation.} s'inspirer de cette propriété et demander à \ST de remplacer le point décimal par une virgule entre accolades avec la commande \verbinline-\STsetdecimalsep{{,}}-. Dans ces deux tableaux où chaque cellule est en mode math, on constate que l'espacement après la virgule est neutralisé pour le second : - -\begin{minipage}{0.65\linewidth} -\begin{lstlisting} -\STsetdecimalsep{,} -\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline -@x & @y & @\text{Moyenne}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab}\par\smallskip -\STsetdecimalsep{{,}} -\begin{spreadtab}{{tabular}{|*3{>{$}r<{$}}|}}\hline -@x & @y & @\text{Moyenne}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.35\linewidth} -\centering -\STsetdecimalsep{,} -\begin{spreadtab}{{tabular}{|*3{>$r<$}|}}\hline -@x & @y & @\text{Moyenne}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab}\par\smallskip -\STsetdecimalsep{{,}} -\begin{spreadtab}{{tabular}{|*3{>$r<$}|}}\hline -@x & @y & @\text{Moyenne}\\\hline -5 & -4 & (a2+b2)/2\\ --6.1 & -8 & (a3+b3)/2\\ -9.85 & 3.7 & (a4+b4)/2\\\hline -\end{spreadtab} -\end{minipage} - -\subsection{Mise en forme des nombres} -Comme cela a été précisé, tous les calculs sont faits par le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/fp/}{\texttt{\textbf{fp}}} et sa macro \falseverb{\FPeval}\footnote{À ce propos, les notations infixe ou postfixe sont acceptées par {\ttfamily\string\FPeval} ce qui signifie que les formules dans \ST peuvent être indifféremment sous forme infixe ou postfixe. Par exemple, la formule infixe \og\falseverb{a1+b1}\fg{} est équivalente aux formules postfixes \og\falseverb{a1 b1 add}\fg{} ou \og\falseverb{a1 b1 +}\fg.}. Ce package fournit d'extraordinaires possibilités de calcul pour \TeX{} et dispose de toutes les fonctions arithmétiques, scientifiques et trigonométriques usuelles. Les calculs sont faits avec une précision de $10^{-18}$, et les 18 décimales sont affichées lorsqu'un calcul ne tombe pas juste ! Sans prendre des précautions, on peut se retrouver avec beaucoup de chiffres dans les parties décimales de certains résultats. - -Pour se prémunir de ce problème, plusieurs solutions existent : -\begin{itemize} - \item on peut utiliser le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/numprint/}{\texttt{\textbf{numprint}}} qui est ce qui se fait de mieux dans l'affichage des nombres; - \item on peut demander à \verb=fp= d'arrondir un résultat avec sa fonction \verb-round(nombre,entier)- qui arrondit \verb=nombre= avec \verb=entier= chiffres après la virgule; - \item on peut également demander à \ST d'arrondir \emph{tous} les nombres placés dans le tableau à une certaine précision avec la macro \verbinline-\STautoround- dont l'argument est le nombre de chiffres demandés après la virgule. Si l'argument est vide, aucun arrondi n'est fait. Si on utilise la macro étoilée \verbinline-\STautoround*-, la partie décimale est remplie si besoin avec des 0 inutiles. -\end{itemize} -Voici un exemple simple des nombres de 1 à 7 et leurs inverses, arrondis à $10^{-6}$ :\par\nobreak -\begin{lstlisting} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab}\medskip - -\STautoround*{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab}\medskip - -\STautoround*{6} -\begin{spreadtab}{{tabular}{|l|*7{>{\centering\arraybackslash}m{1.35cm}|}}} -\hline -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\\hline -@$x^{-1}$& 1/b1 & 1/c1 & 1/d1 & 1/e1 & 1/f1 & 1/g1 & 1/h1\\\hline -\end{spreadtab} -\end{center} - -Tous les nombres contenus dans le tableau final, qu'ils aient été saisis tels quels ou qu'ils proviennent du résultat d'un calcul sont traités par la macro \verbinline-\STprintnum-. Par défaut, cette macro n'a aucun effet et est programmée de la façon suivante : -\begin{center} - \verbinline-\newcommand\STprintnum[1]{#1}- -\end{center} -Il est possible d'arrondir tous les nombres via la commande \verbinline-\numprint- du package \verb-\numprint-. Pour ce faire, il faut redéfinir la macro \verbinline-\STprintnum- de cette façon :\par\nobreak -\begin{lstlisting} -\renewcommand\STprintnum[1]{\numprint{#1}} -\nprounddigits{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\renewcommand\STprintnum[1]{\numprint{#1}} -\nprounddigits{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & 1 & 2 & 3 & 4 & 5 & 6 &7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{center} - -Voici un autre exemple similaire où l'on teste si le nombre à afficher est négatif avec la commande \verbinline-\FPifneg- du package \verb-fp-. Si tel est le cas, le nombre est affiché en rouge. La commande \verbinline-\STautoround- a été préférée à \verbinline-\nprounddigits- du package \verb-numprint- puisque cette dernière ajoute des 0 inutiles. On a également remis le point décimal par défaut puisque \verbinline-\numprint- est en charge de l'affichage des nombres. -\begin{lstlisting} -\STsetdecimalsep{.} -\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} -\STautoround{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STsetdecimalsep{.} -\renewcommand\STprintnum[1]{\FPifneg{#1}\color{red}\fi\numprint{#1}} -\STautoround{6} -\begin{spreadtab}{{tabular}{cccccccc}} -@$x$ & -1 & 2 & -3 & 4 & -5 & 6 & -7 \\\hline -@$1/x$ &1/b1&1/c1&1/d1&1/e1&1/f1&1/g1&1/h1 -\end{spreadtab} -\end{center} - -\subsection{Retours à la ligne et filets horizontaux} -Pour bien délimiter la fin d'une ligne, \ST est contraint de reconnaître les retours à la ligne et les filets horizontaux. Ce package permet d'utiliser dans le tableau l'argument optionnel de \verb-\\- de cette façon : \verb-\\[]-. - -Pour les filets horizontaux, on peut utiliser autant de fois que l'on veut: -\begin{itemize} - \item \verb-\hline-; - \item \verb=\cline{x-y}= où \falseverb x et \falseverb y sont les numéro des colonnes de départ et d'arrivée du filet; - \item \verb=\hhline{}= où \verb== est le type de ligne désirée (voir la documentation du package \href{http://www.ctan.org/tex-archive/macros/latex/required/tools/}{\texttt{\textbf{hhline}}}). - \item n'importe quelle commande du package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/booktabs/}{\texttt{\textbf{booktabs}}}, à savoir \verb-\toprule-, \verb-\midrule-, \verb-\bottomrule-, \verb-\cmidrule-, \verb-\addlinespace-, \verb-\morecmidrule- et \verb-\specialrule-. Tous les arguments de ces macros, optionnels ou pas sont gérés; - \item \verbinline-\noalign- et son argument peuvent être placés après \verb-\\- et pris en compte. -\end{itemize} -Voici le triangle de Pascal inversé, et massacré pour l'exemple :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*5c}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline -[0,1] & [-1,1] & & & \\ \cline{2-4} -1 & & & & \\ \hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{*5c}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\[1em] -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ \hline\hline -[0,1] & [-1,1] & & & \\ \cline{2-4} -1 & & & & \\ \hline -\end{spreadtab} -\end{center} - -\subsection{Masquer une ligne ou une colonne} -Parfois, une colonne ou une ligne entière est destinée à recevoir des calculs intermédiaires qui n'ont pas à être affichés dans le tableau final. Pour cela \ST dispose de deux séquences de contrôle \verbinline=\SThiderow= et \verbinline=\SThidecol= qui, lorsqu'elles sont placées dans une cellule, masquent la ligne ou la colonne dans laquelle se trouve cette cellule. - -Voici un exemple :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ valeurs de $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline -@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ -@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ -@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|ccc|}} -\hline -@ valeurs de $x$ & -1 & 0\SThidecol & 2 & 3 \\\hline -@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ -@$g(x)=x-10$\SThiderow & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ -@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline -\end{spreadtab} -\end{center} -On peut observer comment on masque la ligne contenant $g(x)$ et la colonne correspondant à la valeur 0. - -Il faut se souvenir que les lignes et les colonnes masquées sont \emph{invisibles} pour l'environnement tableau choisi par l'utilisateur, ce qui explique que dans le préambule du tableau, seules 4 colonnes (\falseverb{|r|ccc|}) aient été définies et non 5 comme le voit \ST. - -Pour voir la différence, voici le tableau obtenu en définissant 5 colonnes et en ne masquant aucune ligne ni colonne :\par\nobreak -\begin{center} -\begin{spreadtab}{{tabular}{|r|cccc|}} -\hline -@ valeurs de $x$ & -1 & 0 & 2 & 3 \\\hline -@$f(x)=2x-1$ & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 & 2*[0,-1]-1 \\ -@$g(x)=x-10$ & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 & [0,-2]-10 \\ -@$h(x)=1-x$ & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] & 1-[0,-3] \\\hline -\end{spreadtab} -\end{center} - -\subsection{Sauvegarder la valeur d'une cellule} -On peut être amené à avoir besoin de la valeur numérique d'une cellule dans le tableau pour l'afficher en dehors d'une formule ou même à l'extérieur du tableau. On doit alors utiliser la commande :\par\nobreak -\begin{center} -\verbinline-\STsavecell{}{}- -\end{center} -Avec un \verbinline-\global\def-\footnote{La commande \texttt{\string\def} ne vérifie pas si la macro qu'elle définit existe déjà.}, cette commande a pour effet de sauvegarder de façon globale dans \falseverb{} le résultat de la formule contenue dans la cellule \falseverb{}. - -On ne peut utiliser que des références \emph{absolues}; les références relatives ne sont pas acceptées car cette commande doit se placer dans l'argument optionnel de l'environnement \verbinline-spreadtab-. - -Exemple :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} -\hline -10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline -\end{spreadtab} -\par\medskip -Voici la cellule c1 : \result -\end{lstlisting} -\begin{center} -\begin{spreadtab}[\STsavecell\result{c1}]{{tabular}{|c|c|c|c|c|}} -\hline -10 & a1+10 & b1+10 & a1+b1+c1 & @cell c1 : \result\\\hline -\end{spreadtab} -\par\medskip -Voici la cellule c1 : \result -\end{center} -Si l'on veut sauvegarder plusieurs cellules, on peut mettre autant de fois que l'on veut la commande \verbinline-\STsavecell- dans l'argument optionnel. - -Exemple :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline -@Vitesse (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ -@distance (km) & & & & 180\\\hline -@Temps (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline -\end{spreadtab}\par\medskip -On met au moins \hhh\ heures -\end{lstlisting} -\begin{center} -\begin{spreadtab}[\STsavecell\hhh{b3}\STsavecell\mmm{c3}\STsavecell\sss{d3}]{{tabular}{|rc|}}\hline -@Vitesse (km/h) &\SThidecol&\SThidecol&\SThidecol& 35 \\ -@distance (km) & & & & 180\\\hline -@Temps (h min s) & trunc(e2/e1,0) & trunc(60*(e2/e1-b3),0) & trunc(3600*(e2/e1-b3)-60*c3,1) &@\hhh\ h \mmm\ min \sss\ s\\\hline -\end{spreadtab}\par\medskip -On met au moins \hhh\ heures -\end{center} - -\subsection{Afficher la valeur d'une cellule} -Pour afficher la valeur du champ numérique d'une cellule dans le champ textuel, on vient de voir qu'on pouvait sauvegarder cette valeur dans une séquence de contrôle et se servir de cette séquence de contrôle pour l'afficher ensuite. Le procédé est un peu fastidieux et détourne de ses intentions la commande \verbinline-\STsavecell- qui sert surtout à sauvegarder une valeur pour l'utiliser en dehors du tableau. - -Pour afficher simplement la valeur du champ numérique d'une cellule dans un champ textuel, on peut utiliser la syntaxe \verb-<>- qui sera remplacé par la valeur numérique de la cellule \verb-référence- où la \verb-référence- peut être relativess ou absolue. Si ce qui est entre \verb-<<- et \verb->>- n'est pas une référence, alors rien n'est fait et \verb-<>- est laissé en l'état. La \verb-référence- ne doit contenir aucun espace. Si on écrit \verb-<< a1>>- alors, l'espace fait que la référence n'est pas reconnue et rien ne sera fait. - -Exemple dans une cellule purement textuelle \verb-a3- : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{lr}} -@Prix de vente & 250 \\ -@Prix d'achat & 216 \\\hline -@B\'en\'efice (<>-<>) & b1-b2 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{lr}} -@Prix de vente & 250 \\ -@Prix d'achat & 216 \\\hline -@B\'en\'efice (<>-<>) & b1-b2 -\end{spreadtab} -\end{center} -Exemple dans la cellule mixte c1 : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -23 & 32 & Moyenne $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|c|c||c|}}\hline -23 & 32 & Moyenne $= \frac{<>+<>}{2}= :={(a1+b1)/2}$\\\hline -\end{spreadtab} -\end{center} -Les caractères qui délimitent la référence valent "\verb-<<-" et "\verb->>-" par défaut. Ils peuvent être modifiés avec la commande \verbinline-\STsetdisplaymarks- dont les 2 arguments définissent le délimiteur de gauche et le délimiteur de droite. En écrivant \verbinline-\STsetdisplaymarks{|}{|}-, on devra écrire \verb-|référence|- pour provoquer l'affichage du champ numérique de la cellule \verb-référence-. - -\subsection{Utiliser \ttfamily\textbackslash multicolumn} -Le package \ST est compatible avec la syntaxe \verbinline=\multicolumn{}{}{}= qui fusionne \falseverb{} cellules en une cellule de type et de contenu spécifiés dans les arguments. - -En utilisant \verbinline=\multicolumn=, \ST permet même de conserver une certaine cohérence au niveau du référencement des cellules. Sur ce tableau où des cellules sont fusionnées, les cases du tableau contiennent les références absolues vues par \ST :\par\nobreak -\begin{center} -\ttfamily -\begin{tabular}{|*7{c|}}\hline -a1&b1&c1&d1&e1&f1&g1\\\hline -a2&\multicolumn{2}{l|}{b2}&d2&e2&f2&g2\\\hline -\multicolumn{3}{|l|}{a3}&d3&\multicolumn{2}{l|}{e3}&g3\\\hline -\end{tabular} -\end{center} -Ainsi, quelque soit le nombre de cellules fusionnées, la cellule suivante porte un numéro de colonne qui tient compte du nombre de cellules fusionnées. - -Sur la dernière ligne, les cellules \falseverb{a3}, \falseverb{b3} et \falseverb{c3} sont fusionnées, et si la cellule \falseverb{a3 }contient une formule, les cellules \falseverb{b3} et \falseverb{c3} \emph{n'existent pas} pour \ST : on ne peut nulle part faire référence à ces cellules. - -Voici un exemple où chaque nombre de la ligne du haut est le produit des 2 nombres se trouvant au dessous de lui :\par\nobreak -\begin{lstlisting} -\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} -\begin{spreadtab}{{tabular}{*6{K{0.5}}}} -\cline{2-5} -&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline -\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\newcolumntype{K}[1]{@{}>{\centering\arraybackslash}p{#1cm}@{}} -\begin{spreadtab}{{tabular}{*6{K{0.5}}}} -\cline{2-5} -&\multicolumn{2}{|K{1}|}{:={a2*c2}} & \multicolumn{2}{K{1}|}{:={c2*e2}} &\\\hline -\multicolumn{2}{|K{1}}{:=8}&\multicolumn{2}{|K{1}}{:=7}&\multicolumn{2}{|K{1}|}{:=6}\\\hline -\end{spreadtab} -\end{center} -On remarque que le marqueur de champ numérique \og\falseverb{:=}\fg{} est nécessaire dans chaque cellule où se trouve la commande \verbinline-\multicolumn-. On comprend en effet que si ce marqueur n'existait pas, la totalite de la cellule, c'est-à-dire \verb-\multicolumn{2}{|c|}{}- serait considérée comme étant une formule. - -\section{Macro-fonctions} -L'extension \falseverb{fp} fournit un nombre conséquent d'opérations et de fonctions. Malgré tout, dans le cadre d'un package comme \ST, celles-ci peuvent être insuffisantes et il est possible au programmeur averti d'écrire des macro-fonctions supplémentaires en utilisant celles fournies par \falseverb{fp}. Cette section présente les macro-fonctions pour l'instant disponibles\footnote{Bien d'autres restent à écrire ! Elles seront disponibles dans des versions futures de \ST.}. Il y aura plus de précisions sur la méthode pour programmer des macro-fonctions dans la prochaine version de ce manuel. - -\subsection{Macro-fonctions mathématiques} -\subsubsection{Sommer des cellules} -La fonction \og\verbinline=sum=\fg permet de faire la somme d'une ou plusieurs plages de cellules. - -Elle s'utilise ainsi : \verbinline=sum(;;...;)=, où une plage de cellules est : -\begin{itemize} - \item soit une cellule isolée comme \og\falseverb{a1}\fg{} ou \og\falseverb{[2,1]}\fg{}; - \item soit une zone rectangulaire délimitée par la cellule supérieure gauche et inférieure droite de cette façon : \og\verb=:=\fg, à condition que \og\verb==\fg se trouve \emph{avant} \og\verb==\fg{} lorsqu'on parcourt le tableau de haut en bas, de gauche à droite.\par - Voici des exemple de plages de cellules : \og\falseverb{a2:d5}\fg{}, \og\falseverb{[-1,-1]:[2,3]}\fg{}, \og\falseverb{b4:[5,1]}\fg{}. -\end{itemize} -Dans les plages de cellules, les cellules vides ou ne contenant que du texte sont considérées comme contenant le nombre 0. Il en est de même pour les cellules masquée car fusionnées par \verbinline-\multicolumn-. - -Les références relatives et absolues peuvent être utilisées conjointement, comme il semble bon à l'utilisateur. Voici un exemple où l'on fait la somme des coefficients du triangle de Pascal :\par\nobreak -\begin{minipage}{0.75\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*5c}} -\multicolumn{5}{c}{somme=:={sum(a2:e6)}}\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1] & & & \\ -1 & & & & -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.25\linewidth} -\centering -\begin{spreadtab}{{tabular}{*5c}} -\multicolumn{5}{c}{somme=:={sum(a2:e6)}}\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1] & & & \\ -1 & & & & -\end{spreadtab} -\end{minipage}% - -\subsubsection{Macro-fonction \ttfamily fact} -La macro-fonction \verbinline=fact()= permet de calculer la factorielle de son argument, sous réserve que celui-ci soit un entier compris entre 0 et 18 inclus pour éviter des débordements\footnote{En effet, pour \falseverb{fp} le plus grand entier est $10^{18}-1$. La factorielle de 19 dépasse ce nombre.}. Le \falseverb{} peut aussi être une référence vers une cellule contenant un nombre entier. - -Voici les factorielles de 0 à 8 :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*9c}} - 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline -fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{*9c}} - 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 &8\\\hline -fact(a1)&fact(b1)&fact(c1)&fact(d1)&fact(e1)&fact(f1)&fact(g1)&fact(h1)&fact(i1) -\end{spreadtab} -\end{center} - -\subsubsection{Macro-fonction \ttfamily sumprod} -La fonction \verbinline=sumprod= permet de multiplier les éléments correspondants de 2 plages ou plus et ensuite, additionner ces produits. - -Cette fonction s'utilise ainsi : \verbinline{sumprod(;;...;)}. Toutes les plages rectangulaires doivent avoir les mêmes dimensions. - -Voici un exemple simple où l'on calcule l'âge moyen d'un groupe d'enfants âgés de 10 à 15 ans :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{r*6c}} -@\^Ages & 10 & 11 & 12 & 13 & 14 & 15\\ -@Nombre & 5 & 8 & 20 & 55 & 9 & 3\\\hline -@Moyenne&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{r*6c}} -@\^Ages & 10 & 11 & 12 & 13 & 14 & 15\\ -@Nombre & 5 & 8 & 20 & 55 & 9 & 3\\\hline -@Moyenne&\multicolumn{6}{l}{:={sumprod(b1:g1;b2:g2)/sum(b2:g2)}} -\end{spreadtab} -\end{center} -De la même façon que pour la macro-fonction \verbinline-sum-, les cellules de texte, vides ou fusionnées par un \verbinline-\multicolumn- sont considérées comme contenant le nombre 0. - -\subsubsection{Nombres aléatoires} -Les macro-fonctions \verbinline-randint- et \verbinline-rand- renvoient un nombre aléatoire. - -À noter : la \og graine\fg{} qui initialise la suite aléatoire dépend de la date ainsi que de la la minute à laquelle est faite la compilation. Les séries aléatoires données par cette fonction changeront entre deux compilations faites à des heures dont les minutes diffèrent. Si l'on veut vraiment avoir des nombres aléatoires indépendant du moment de compilation et donc reproductibles, il faut neutraliser la macro interne \verb-\ST@seed- et définir une graine pour \verb-fp- :\par\nobreak -\begin{lstlisting}[backgroundcolor=\color{ST@codebckgcolor}] -\makeatletter -\renewcommand\ST@seed{}% redefinit la macro interne -\makeatother -\FPseed=27% donne une graine (n'importe quel entier) a fp -\end{lstlisting} -La macro fonction \verbinline-randint([,])- renvoie une nombre \emph{entier} qui dépend des paramètres : \verb== est un entier optionnel qui vaut 0 par défaut. L'entier aléatoire renvoyé est compris dans l'intervalle \verb=[;]=. - -La macro fonction \verbinline-rand()- renvoie un nombre aléatoire décimal compris entre 0 et 1 :\par\nobreak -\begin{lstlisting} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|cccc|}}\hline -@nombres dans [0;1] &rand() &rand() &rand() &rand() \\ -@nombres dans [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ -@nombres dans [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ -\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STautoround{6} -\begin{spreadtab}{{tabular}{|l|cccc|}}\hline -@nombres dans [0;1] &rand() &rand() &rand() &rand() \\ -@nombres dans [-5;5] &randint(-5,5) &randint(-5,5) &randint(-5,5) &randint(-5,5)\\ -@nombres dans [0;20] &randint(20) &randint(20) &randint(20) &randint(20) \\ -\hline -\end{spreadtab} -\end{center} - -\subsubsection{PGCD et PPCM} -Les macros fonctions "gcd" et "lcm" peremttent de calculer le Plus Grand Commun Diviseur (PGCD) et le Plus Petit Commun Multiple (PPCM) des nombres passés en arguments et séparés par des virgules : -\begin{center} -\verbinline-gcd(nombre1,nombre2,...,nombreN)-\par -\verbinline-lcm(nombre1,nombre2,...,nombreN)- -\end{center} -Exemple : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline -\multicolumn3{|c||}{@Nombres}& @PGCD & @PPCM \\\hline -24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ -15 & 10 & 25 & & \\ -16 & 12 & 15 & & \\ -\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|r|r||c|c|}}\hline -\multicolumn3{|c||}{@Nombres}& @PGCD & @PPCM \\\hline -24 & 18 & 12 & \STcopy{v}{gcd(a2,b2,c2)} & \STcopy{v}{lcm(a2,b2,c2)}\\ -15 & 10 & 25 & & \\ -16 & 12 & 15 & & \\ -\hline -\end{spreadtab} -\end{center} - -\subsubsection{Écriture scientifique} -La macro fonction "scitodec" permet de convertir un nombre écrit en écriture scientifique en nombre décimal compréhensible par \ST pour faire ses calculs. La syntaxe est \verbinline-scitodec()-, où le \verb-- est : -\begin{enumerate}[label=--] - \item une suite de caractères se présentant sous la syntaxe \verb-EE-, où la \verb-- est un nombre décimal et l'\verb->exposant>- est un entier relatif. Les "E" peuvent être écrit en majuscule ou minuscule. - - Le nombre ainsi représenté est $\text{\ttfamily }\times10^{\text{\ttfamily }}$ - \item une référence au champ \emph{textuel} d'une cellule qui doit contenir des caractères obéissants à la syntaxe vue au point précédent. -\end{enumerate} -Exemple : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|r|}}\hline -@Écritures scientifiques & @Écritures décimales \\\hline -@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ -@-3.1EE-3 & \\ -@15ee5 & \\ -@-0.025ee7 & \\ -@2.125EE0 & \\ -@3.1575EE-4 & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|r|}}\hline -@Écritures scientifiques & @Écritures décimales \\\hline -@4EE2 & \STcopy{v}{scitodec([-1,0])}\\ -@-3.1EE-3 & \\ -@15ee5 & \\ -@-0.025ee7 & \\ -@2.125EE0 & \\ -@3.1575EE-4 & \\\hline -\end{spreadtab} -\end{center} - -\subsubsection{Identité} -La plus simple des macros fonctions est \og\verbinline=id()=\fg. Celle-ci renvoie le nombre qui se trouve entre parenthèses. Mathématiquement, elle ne sert pas à grand chose, mais avec \ST, elle permet de passer des expressions mathématiques à des macros qui n'en admettent pas. On peut ainsi s'en servir dans les plages de cellules de \verbinline=sum= par exemple. - -Dans le code ci dessous, la macro \verbinline=id= est utilisée pour déterminer la plage de cellules à additionner avec \verbinline-sum-. Dans cet exemple, la valeur du champ numérique de la cellule a2 vaut 8. Et donc, "\verbinline=sum([0,-1]:[id(a2-1),-1])/a2=" est équivalent à \verbinline=sum([0,-1]:[7,-1])/8= : - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{r*{10}c}} - @Entiers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ -Moyenne des :={8} premiers entiers & sum([0,-1]:[id(a2-1),-1])/a2 \\ -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{r*{10}c}} - @Entiers & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ -Moyenne des :={8} premiers entiers & sum([0,-1]:[id(a2-1),-1])/a2 \\ -\end{spreadtab} -\end{center} - -\subsection{Macro-fonctions de test} -Elles sont au nombre de 3 et ont la syntaxe suivante :\par\nobreak -\begin{center} -\verbinline=ifeq(nombre1,nombre2,nombre3,nombre4)=\par -\verbinline=ifgt(nombre1,nombre2,nombre3,nombre4=\par -\verbinline=iflt(nombre1,nombre2,nombre3,nombre4)= -\end{center} -La comparaison se fait entre \falseverb{nombre1} et \falseverb{nombre2} : -\begin{itemize} - \item test d'égalité pour \verbinline-ifeq- : \falseverb{nombre1} = \falseverb{nombre2} ? - \item test de supériorité stricte pour \verbinline-ifgt- : \falseverb{nombre1} > \falseverb{nombre2} ? - \item test d'infériorité stricte pour \verbinline-iflt- : \falseverb{nombre1} < \falseverb{nombre2} ? -\end{itemize} -Si le test est vrai, \falseverb{nombre3} est retourné, sinon c'est \falseverb{nombre4}. - -À titre d'exemple, voici quelques valeurs de la fonction -$f(x)=\begin{cases} -10 &\text{si }x<1\\ -0 &\text{si }x=1\\ --10 &\text{si }x>1 -\end{cases} -$\smallskip - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*2c|}}\hline -@$x$ & @$f(x)$ \\\hline --0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*2c|}}\hline -@$x$ & @$f(x)$ \\\hline --0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\ -[0,-1]+0.5 & iflt([-1,0],1,10,ifeq([-1,0],1,0,-10))\\\hline -\end{spreadtab} -\end{center} - -\subsection{Macro-fonctions de date} -\subsubsection{Convertir une date en nombre avec \ttfamily frshortdatetonum}\label{datetonum} -La macro \verbinline-frshortdatetonum- permet de convertir une date de la forme 14/7/1789 en un nombre qui est en fait le nombre de jours écoulés depuis le 1\ier{} mars de l'an 0\footnote{Cet \og an 0\fg{} n'existe d'ailleurs pas, mais cela ne devrait pas être gênant pour les dates contemporaines}. Il est important de noter que cette macro-fonction requiert un argument \emph{textuel} et non pas un nombre ou le résultat d'un calcul mathématique. Par conséquent, si l'argument de cette macro-fonction fait référence à une cellule, cette cellule \emph{doit} être une cellule textuelle, c'est à dire contenant \og\verb-@-\fg{} ou \og\verb-:={}-\fg{} - -Dans l'exemple ci-dessous, les deux premières lignes montrent que la cellule de gauche contient une date, et la cellule de droite fait référence à cette date pour calculer le nombre correspondant. La troisième ligne montre dans la cellule de gauche la date 0, mais surtout calcule dans la cellule de droite le nombre correspondant à la date \emph{d'aujourd'hui}, en transformant en nombre les compteurs de \TeX{} \verbinline-\day-, \verbinline-\month- et \verbinline-\year- qui contiennent les numéros des jours, mois et année courants.\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{cc}} -@14/7/1789 & frshortdatetonum(a1)\\ -1/1/2001 :={} & frshortdatetonum(a2)\\\hline -frshortdatetonum(1/3/0) & frshortdatetonum(\number\day/\number\month/\number\year) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{cc}} -@14/7/1789 & frshortdatetonum(a1)\\ -1/1/2001 :={} & frshortdatetonum(a2)\\\hline -frshortdatetonum(1/3/0) & frshortdatetonum(\number\day/\number\month/\number\year) -\end{spreadtab} -\end{center} -Une autre macro-fonction existe, elle transforme une date longue du type \og 25 décembre 1789\fg{} en un nombre. L'argument peut aussi être la séquence de contrôle \verbinline-\today- si l'on a pris le soin de charger l'extension \verb-babel- avec l'option \verb-frenchb-.\par\nobreak -\begin{lstlisting}[escapechar=Z] -\begin{spreadtab}{{tabular}{cc}} -frlongdatetonum(\today) & frlongdatetonum(25 dZéZcembre 2009)\\ -@1 juillet 1970 & frlongdatetonum(a2) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{cc}} -frlongdatetonum(\today) & frlongdatetonum(25 décembre 2009)\\ -@1 juillet 1970 & frlongdatetonum(a2) -\end{spreadtab} -\end{center} - -\subsubsection{Passer d'un nombre à une date} -Plusieurs macro-fonctions permettent de traduire un nombre en une donnée de date. Toutes ces macro-fonctions ont en commun que leur résultat est du \emph{texte}. Par conséquent, \emph{la cellule les contenant deviendra une cellule textuelle} dont le texte sera le résultat de cette fonction. Si un texte cohabitait avec la formule dans cette cellule, le résultat de la formule sera inséré à la place de \verb-:={}-. Il en résulte que la cellule ne peut plus faire l'objet d'aucun traitement mathématique ensuite. - -Voici ces fonctions : -\begin{itemize} - \item \verbinline-numtofrshortdate- transforme un nombre en une date courte du type 14/7/1789; - \item \verbinline-numtofrlongdate- transforme un nombre en une date longue du type \og 14 juillet 1789\fg; - \item \verbinline-numtofrmonth- extrait d'un nombre représentant une date le nom du mois correspondant; - \item \verbinline-numtofrday- extrait d'un nombre représentant une date le nom du jour correspondant. -\end{itemize} -Voici un exemple où l'on se place 1000 jours avant puis 1000 jours après le 1/6/2009. Pour chacune de ces 2 dates, on calcule la date courte, la date longue, le mois et le jour de la semaine.\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{cc}} \hline -\multicolumn{2}{|c|}{@1/6/2009} \\\hline\hline -1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ -1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ -1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ -1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) \\\hline --1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ --1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ --1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ --1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{cc}} \hline -\multicolumn{2}{|c|}{@1/6/2009} \\\hline\hline -1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ -1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ -1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ -1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) \\\hline --1000 & numtofrshortdate(frshortdatetonum(a1)+[-1,0])\\ --1000 & numtofrlongdate(frshortdatetonum(a1)+[-1,0]) \\ --1000 & numtofrmonth(frshortdatetonum(a1)+[-1,0]) \\ --1000 & numtofrday(frshortdatetonum(a1)+[-1,0]) -\end{spreadtab} -\end{center} - -\subsection{Macro fonctions de coordonnées}\label{tag} -Plutôt que de faire référence à une cellule par ses coordonnées qui sont difficiles à mémoriser et qui changent si on insère une ligne ou une colonne, il est parfois bien plus pratique de donner un nom à une cellule et d'y faire référence plus loin par ce nom. - -La macro fonction ``\verbinline-tag()-'' a pour effet de nommer la cellule dans laquelle elle se trouve. Il ne s'agit pas vraiment d'une macro fonction comme les autres puisque ce qu'elle retourne rien lorsqu'elle est mise dans une formule : elle disparait sans provoquer aucun effet sur le résultat mathématique. On peut donc écrire ``\verbinline-tag()-'' \emph{n'importe où} dans le champ numérique d'une cellule. Le \verb-- peut être n'importe quelle suite de caractères alphanumériques, mais il est déconseillé de mettre une lettre et un nombre, qui pourraient être compris comme une référence à une cellule, et serait donc modifié lors d'une opération de copie avec \verbinline-\STcopy-. Cette macro fonction a une action supplémentaire, elle sauvegarde via un \verbinline-\def- la valeur numérique de la cellule dans laquelle elle se trouve de façon à pouvoir y faire appel plus tard \emph{en dehors du tableau} via la commande purement développable \verbinline-\STtag{}-. - -Par la suite dans le tableau, au lieu de mettre les coordonnées de la cellule \verb--, on peut écrire ``\verbinline-cell()-'' qui est une macro fonction qui renvoit les coordonnées de la cellule précédemment nommée. Par exemple si ``\verbinline-tag()-'' a été écrit dans la cellule ``\verb-B3-'' si on a écrit plus loin ``cell()'', cette macro fonction renvoit \verb-B3-. - -Voici un exemple où l'on fait la somme de cellules et l'on donne le nom ``\verb-foo-'' au premier nombre et le nom ``\verb-bar-'' au dernier. On peut observer que \verbinline-tag(foo)- se trouve entre ``1'' et ``9'' et qu'au final, puisque cette macro fonction disparait, le champ numérique de la cellule contiendra ``19'' : -\begin{lstlisting} -\begin{spreadtab}{{tabular}{r@{}r}} - & 15tag(foo) \\ -@+ & 37 \\ -@+ & 13 \\ -@+ & 48 \\ -@+ & 1tag(bar)9 \\\cline{2-2} - & sum(cell(foo):cell(bar))tag(baz) -\end{spreadtab} - -foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{r@{}r}} - & 15tag(foo) \\ -@+ & 37 \\ -@+ & 13 \\ -@+ & 48 \\ -@+ & 1tag(bar)9 \\\cline{2-2} - & sum(cell(foo):cell(bar))tag(baz) -\end{spreadtab} - -foo=\STtag{foo}, bar=\STtag{bar}, baz=\STtag{baz} -\end{center} -Lorsque l'environnement \ST se trouve inclus dans un autre environnement, les affectations faites par la macro fonction \verb-tag- restent \emph{locales} à cet environnement et ne pourraient pas être accessibles en dehors de cet environnement via \verbinline-\STtag-. Dans l'exemple ci-dessous, le tableau fait par \ST est dans un environnement \verb-center- et l'on doit donc utiliser \verbinline-\STmakegtag{}- pour rendre global la sauvegarde de la valeur numérique contenus dans la cellule marquée par ``tag{}'' : - -\begin{minipage}{.6\linewidth} -\begin{lstlisting} -\begin{center} - \begin{spreadtab}{{tabular}{cccc}}\hline - 6&9&17&21\\\hline - \multicolumn{4}{c}{moyenne = :={sum(a1:d1)/4tag(moy)}} - \end{spreadtab} - \STmakegtag{moy} -\end{center} -La moyenne est de \STtag{moy}. -\end{lstlisting} -\end{minipage}\kern6pt -\begin{minipage}{.3\linewidth} -\begin{center} - \begin{spreadtab}{{tabular}{cccc}}\hline - 6&9&17&21\\\hline - \multicolumn{4}{c}{moyenne = :={sum(a1:d1)/4tag(moy)}} - \end{spreadtab} - \STmakegtag{moy} -\end{center} -La moyenne est de \STtag{moy}. -\end{minipage} - -L'argument de \verbinline-\STmakegtag- peut êre constitué de plusieurs noms séparés par des virgules. - -Bien qu'elles soient à première vue moins utiles, \ST fournit également les macros fonctions ``\verbinline-row()-'' et ``\verbinline-col()-'' qui renvoient le numéro de la ligne ou de la colonne où se trouvait \verbinline-tag()-. Voici par exemple une façon de dénombrer des valeurs pour en calculer la moyenne : on nomme ``un'' la première valeur et ``der'' la dernière, et le nombre de valeurs est donc row(der)-row(un)+1 : - -\begin{minipage}{0.6\linewidth} -\begin{lstlisting} -moyenne = \begin{spreadtab}{{tabular}[b]{r}} -7tag(un)\\9\\15\\6\\20\\13\\11\\55tag(der)\\ -\hline -sum(cell(un):cell(der))/(row(der)-row(un)+1) -\end{spreadtab} -\end{lstlisting} -\end{minipage}\hfill -\begin{minipage}{0.35\linewidth} -moyenne = \begin{spreadtab}{{tabular}[b]{r}} -7tag(un)\\9\\15\\6\\20\\13\\11\\55tag(der)\\ -\hline -sum(cell(un):cell(der))/(row(der)-row(un)+1) -\end{spreadtab} -\end{minipage} - -\section{Précautions particulières} -\subsection{Redéfinition des commandes de filets horizontaux} -On peut être tenté de définir une commande pour produire ---~par exemple~--- une double ligne horizontale :\par\nobreak -\begin{center} -\verbinline-\newcommand\dline{\hline\hline}- -\end{center} -puis essayer de l'utiliser dans un tableau pour produire ce simple exemple qui calcule à la seconde ligne les termes de la suite de Fibonacci :\par\nobreak -\begin{center} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{center} -Mais en écrivant ce code, il y a un problème :\par\nobreak -\begin{lstlisting} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -1 & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{lstlisting} -En effet la compilation échoue et dans le log, on peut lire que \verb-\FPeval- se plaint :\par -\hfill\falseverb{! Improper alphabetic constant.}\hfill\null - -La raison est simple, c'est que le \verb-\dline- de la ligne 4, n'est \emph{pas} reconnu par \ST comme un filet horizontal et \emph{il se retrouve donc dans la cellule de la ligne suivante}. Pour \ST, cette cellule \falseverb{b1} contient :\par -\hfill\falseverb{\dline 1}\hfill\null - -Comme il n'y a pas de \verb-@- ni de délimiteur de formule \verb-:={...}-, \verb-\FPeval- essaie vaillamment de calculer ce contenu et échoue évidemment ! - -Pour pouvoir compiler ce code sans erreur, la cellule \falseverb{a2} \emph{doit} contenir un marqueur de champ numérique :\par\nobreak -\begin{lstlisting} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{lstlisting} -\begin{center} -\newcommand\dline{\hline\hline} -\begin{spreadtab}{{tabular}{*7c}} -0 & 1 & 2 & 3 & 4 & 5 & 6 \\\dline -:={1} & 1 & a2+b2 & b2+c2 & c2+d2 & d2+e2 & e2+f2 -\end{spreadtab} -\end{center} - -\subsection{Cohabitation de {\ttfamily\textbackslash multicolumn} et \ttfamily\textbackslash SThidecol} -Tout d'abord, dans une utilisation normale, l'utilisation conjointe de \verbinline|\multicolumn| et \verbinline-\SThiderow- ne doit pas arriver, et la plupart des utilisateurs ne devrait pas rencontrer cette situation ni lire ce chapitre. - -Pour les courageux venons-en au c\oe ur du problème : tout d'abord, une colonne masquée ne doit \emph{jamais} contenir une cellule où se trouve la commande \verbinline-\multicolumn- ! Mais que se passe t-il si une colonne masquée cache des cellules fusionnées par \verbinline-\multicolumn-? - -Déjà, en général, il n'y a pas d'erreur de compilation ni message d'erreur, mais il y a quelques subtilités quant aux références qui sont un peu chamboulées dans la ligne concernée après le \verbinline-\multicolumn-\ldots - -Prenons un exemple, et mettons que dans le tableau suivant, on fusionne les cellules \falseverb{b2} à \falseverb{h2} et que l'on souhaite cacher les colonnes \falseverb{c}, \falseverb{d} et \falseverb{f}, ici en gris :\par\nobreak -\begin{center} -\ttfamily -\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|} -\hline - a1 & b1 & \cellcolor[gray]{0.6}c1 & \cellcolor[gray]{0.6}d1 & e1 & \cellcolor[gray]{0.6}f1 & g1 & h1 & i1 & j1\\\hline - a2 & \multicolumn1c{b2} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1c{} & \multicolumn1{>{\cellcolor[gray]{0.6}}c}{} & \multicolumn1{c}{} & \multicolumn1{c|}{} & i2 & j2\\\hline -\end{tabular} -\end{center} -Il y a 4 cellules \emph{visibles} fusionnées, on écrira donc \verbinline-\multicolumn{4}- car on ne tient \emph{jamais} compte des colonnes masquées dans le décompte du nombre de cellules à fusionner. - -Maintenant, on compte 4 lettres à partir de la lettre \falseverb{b} en l'incluant dans le décompte. On arrive à la lettre \falseverb{e} : cela détermine un intervalle de colonnes \og\falseverb{b-e}\fg. Dans cet intervalle, 2 colonnes masquées sont incluses (\falseverb c et \falseverb d) et 1 colonne masquée n'est pas comprise (\falseverb f). Ces 2 nombres sont importants pour comprendre la suite, aussi, notons-les $x$ et $y$ dans le cas général. - -La règle est la suivante : -\begin{itemize} - \item il faut rajouter $y$ signes \og\verb-&-\fg{} après le \verbinline-\multicolumn- (pour l'exemple, il en faudrait 1). - \item les références des colonnes des cellules qui suivent le \verbinline-\multicolumn- seront décalées de $x$ lettres vers le début de l'alphabet. Pour l'exemple donnée, si on veut faire référence à la cellule marquée \og \falseverb{i2}\fg{}, il faudra écrire \falseverb{g2} (au lieu de \falseverb{i2}). -\end{itemize} -Voici un vrai exemple dont la structure est similaire au précédent : $x=2$ et $y=1$. Dans le code, remarquer le \og\textcolor{red}{\texttt{\&}}\fg{} qui a été ajouté puisque $y=1$. Par ailleurs, on reste simple avec les formules, on ajoute 1 au nombre du dessus :\par\nobreak -\begin{lstlisting}[escapechar=Z] -\begin{spreadtab}{{tabular}{|*{7}{c|}}} -\hline -1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline -a1+1& \multicolumn4{l|}{:={b1+1}}Z\ttfamily\color{red}\rlap\&Z & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*{7}{c|}}} -\hline -1 & 2 & \SThidecol3 & \SThidecol4 & 5& \SThidecol6 & 7& 8& 9 & 10 \\\hline -a1+1& \multicolumn4{l|}{:={b1+1}}& & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & g2+1 & h2+1\\\hline -\end{spreadtab} -\end{center} -Voici encore un exemple similaire où une seule colonne est masquée (la colonne \falseverb d), et où $x=1$ et $y=0$ :\par\nobreak -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*{9}{c|}}} -\hline -1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline -a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*{9}{c|}}} -\hline -1 & 2 & 3 & \SThidecol4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline -a1+1& \multicolumn6{l|}{:={b1+1}} & i1+1 & j1+1\\\hline -a2+1& b2+1 & & & & & & & h2+1 & i2+1\\\hline -\end{spreadtab} -\end{center} - -\subsection{Messages émis par \ST} -Le package émet des messages d'erreur et arrête la compilation dans ces cas : -\begin{itemize} - \item Pour calculer une cellule, on calcule de proche en proche des cellules qui par le jeu des références, reviennent sur la cellule d'origine (références circulaires). Dans ce cas, l'arbre des dépendances est affiché dans le message d'erreur; - \item une formule nécessitant un nombre fait référence à une cellule vide ou ne contenant que du texte; - \item une cellule fait référence à une cellule non définie (hors limite du tableau); - \item une cellule fait référence à une cellule fusionnée par un \verbinline-\multicolumn-; - \item une référence relative entre crochets ne respecte pas la syntaxe. -\end{itemize} - -Le package peut émettre des messages d'information (dans le fichier de log), ce qu'il fait par défaut. La commande \verbinline-\STmessage- permet ou pas l'émission de messages d'information. Pour chacune des ces altenatives, la syntaxe est la suivante : \verbinline-\STmessage{true}- ou \verbinline-\STmessage{false}-. - -Pour comprendre la signification des messages, prenons un tableau simple :\par\nobreak -\begin{minipage}{0.65\linewidth} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|cccc|c|}}\hline -b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline -\end{spreadtab} -\end{lstlisting} -\end{minipage}% -\begin{minipage}{0.35\linewidth} -\centering -\begin{spreadtab}{{tabular}{|cccc|c|}}\hline -b1+1 & c1+1 & d1+1 & 10 & a1+b1+c1+d1\\\hline -\end{spreadtab} -\end{minipage} - -Le fonctionnement du tableau est ici très simple à comprendre. Voici les informations délivrées par \ST :\par\nobreak -\begin{lstlisting} -[spreadtab] New spreadtab {tabular}{|cccc|c|} -* reading tab: ok -* computing formulas: - cell A1-B1-C1 - cell B1 - cell C1 - cell D1 - cell E1 -* building tab: ok -[spreadtab] End of spreadtab -\end{lstlisting} -L'environnement spécifié par l'utilisateur est repris entre parenthèses (ici \verbinline-{tabular}{|cccc|c|}-). Précédées d'une étoile, on retrouve les 3 étapes nécessaires à \ST pour mener à bien sa mission : lecture du tableau, calcul des formules et construction du tableau final. - -Pour la seconde étape, les cellules sont évaluées de haut en bas, de gauche à droite : \ST indique qu'il commence par essayer de calculer la première cellule \falseverb{A1}. Pour cela, il indique qu'il doit d'abord évaluer \falseverb{B1} et avant cela encore, évaluer \falseverb{C1}. Comme il n'y a plus de cellule après \falseverb{C1}, c'est qu'elle peut être évaluée; en effet, elle ne dépend que de \falseverb{D1} qui est un nombre égal à 10. - -Pour chaque ligne suivante, il n'y a qu'une seule cellule ce qui signifie que lorsque \ST essaie de les évaluer, elles l'ont déjà été et sont des nombres ou alors, elles ne font références qu'à des cellules déjà calculées. - -\subsection{Débogage} -Pour faciliter l'utilisation de \ST, un mode de débogage est disponible. Il est activé lorsque la commande \verbinline-\STdebug- est présente dans l'argument optionnel de l'environnement \verb-spreadtab-. Cette commande change le comportement de \ST qui, au lieu d'afficher le tableau final, affiche un (ou plusieurs) tableau de débogage. Cet affichage se fait juste après que \ST ait lu l'ensemble de toutes les cellules ; aucun calcul de formule n'a encore eu lieu. Il y a autant de tableaux affichés que de commande \verbinline-\STdebug- présentes, sous réserve que leur argument soit différent. Seuls 3 arguments sont possibles, et voici ce qu'il permettent : -\begin{itemize} - \item \verbinline-\STdebug{formula}- : affichage des champs numériques de toutes les cellules et les fins de ligne; - \item \verbinline-\STdebug{text}- : affichage des champs textuels de toutes les cellules; - \item \verbinline-\STdebug{code}- : affichage du code interne que \ST affecte à chaque cellule. Ce code interne est assigné à chaque cellule lors de la lecture du tableau. Il vaut : - \begin{enumerate}[label=\small\textbullet] - \item $-1$ s'il s'agit d'une cellule fusionnée par une commande \verbinline-\multicolumn-; - \item 0 si la cellule est vide ou purement textuelle; - \item 1 si le champ numérique de la cellule contient une formule qui sera à évaluer plus tard; - \item 2 si la champ numérique de la cellule contient un nombre. - \end{enumerate} -\end{itemize} - -Lorsque le mode débogage est activé, le tableau final \emph{n'est pas affiché}. Il est cependant possible de forcer cet affichage en mettant la commande \verbinline-\STdisplaytab- dans l'argument optionnel. - -Voici un tableau sur lequel s'appuiera l'exemple suivant : - -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|r|r|r|}}\hline -@$x$ &@$y$ & @$x+y$\\\hline\hline -22 & 54 & \STcopy{v3}{a2+b2} \\ -43 & 65 & \\ -49 & 37 & \\\hline -$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline -\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|r|r|r|}}\hline -@$x$ &@$y$ & @$x+y$\\\hline\hline -22 & 54 & \STcopy{v3}{a2+b2} \\ -43 & 65 & \\ -49 & 37 & \\\hline -$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline -\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} -\end{spreadtab} -\end{center} -On va demander à ce que \ST affiche les 3 tableaux de débogage possibles concernant le tableau ci-dessus. Pour cela, il suffit de modifier la ligne 1 du code ci-dessus comme ceci : - -\hfill\verbinline[basicstyle=\ttfamily\small]-\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline-\hfill\kern0pt -\begin{center} -\begin{spreadtab}[\STdebug{text}\STdebug{formula}\STdebug{code}]{{tabular}{|rr|r|}}\hline -@$x$ &@$y$ & @$x+y$\\\hline\hline -22 & 54 & \STcopy{v3}{a2+b2} \\ -43 & 65 & \\ -49 & 37 & \\\hline -$Sx=:={a2+a3+a4}$ & $Sy=:={b2+b3+b4}$ & $Sx+Sy=:={}$\\\hline -\multicolumn2{|r|}{$Sy-Sx=:={b5-a5}$} & @\multicolumn1c{}\\\cline{1-2} -\end{spreadtab} -\end{center} -Ces 3 tableaux de débogage peuvent aider à comprendre un peu mieux le fonctionnement interne de \ST. On peut observer dans le tableau 2 que toutes les cellules ayant un champ numérique ont un code interne de 1 ou 2 (voir tableau 3) et ont un marqueur de champ numérique "\verb-:=-" qui leur est associé (voir tableau 1). Ce marqueur représente l'endroit où sera inséré ---~par substitution~--- le résultat du calcul du champ numérique. C'est donc à partir des contenus des champs textuels du tableau 1 et par simple substitution, qu'une fois les champs numériques calculés, les cellules sont reconstituées pour donner celles du tableau final. - -Dans les tableaux ci-dessus, les cellules contenant les coordonnées ne sont grisées que si le package \href{http://www.ctan.org/tex-archive/macros/latex/contrib/colortbl/}{\texttt{\textbf{colortbl}}} a été chargé. - -\section{Exemples} -Voici quelques tableaux pour finir ! - -Afin que l'on sache quels nombres sont calculés, seuls les nombres non calculés sont en \textcolor{red}{rouge}. Dans ces tableaux, beaucoup d'artifices (des struts, des multicolumn) et des packages (notamment numprint et ses colonnes \og N\fg{} qui alignent les séparateurs décimaux) ont été utilisés pour obtenir un résultat satisfaisant. Le code est parfois lourd et peu lisible, mais il ne s'agit pas ici d'exemples basiques mais de tableaux peaufinés ! - -\subsection{Encore un triangle de Pascal} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{*7r}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ -[0,1] & [-1,1] & & & & & \\ -\color{red}:={1}& & & & & & -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{*7r}} -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]\\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1]+[0,1] & [-1,1] & & & \\ -[0,1] & [-1,1]+[0,1] & [-1,1] & & & & \\ -[0,1] & [-1,1] & & & & & \\ -\color{red}:={1}& & & & & & -\end{spreadtab} -\end{center} - -\subsection{Convergence d'une série} -Pour les matheux, il s'agit du développement limité de la fonction exponentielle en \numprint{0.5}. En effet, -\[\forall x\in \mathbf{R}\qquad e^x=\sum_{k=0}^\infty\frac{x^k}{k!}\] -et le tableau illustre la rapidité de la convergence au fur et à mesure de l'ordre du développement limité.\par\nobreak -\begin{lstlisting} -\STautoround{15} -\renewcommand\STprintnum[1]{\numprint{#1}} -\begin{spreadtab}{{tabular}{cc}} -\multicolumn{2}{c}{Convergence en $x=\color{red}:={0.5}$}\\[1.5ex] -@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline -\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ -\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\STautoround{15} -\renewcommand\STprintnum[1]{\numprint{#1}} -\begin{spreadtab}{{tabular}{cc}} -\multicolumn{2}{c}{Convergence en $x=\color{red}:={0.5}$}\\[1.5ex] -@$n$ & e^a1\SThidecol & @ $\displaystyle e^{\numprint{<>}}-\sum_{k=0}^n\frac{\numprint{<>}^k}{k!}$\\[3ex]\hline -\color{red}:={0}& a1^[-1,0]/fact([-1,0]) & \STcopy{v}{b!2-b3}\\ -\STcopy{v}{a3+1}& \STcopy{v}{a!1^a4/fact(a4)+b3}& \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\ - & & \\\hline -\end{spreadtab} -\end{center} - -\subsection{Convergence vers le nombre d'or} -Voici la définition des nombres de Fibonacci : $F_0=1\qquad F_1=1\qquad F_{n+2}=F_{n+1}+F_n$ - -On va mettre ici en évidence que le quotient de 2 nombres de Fibonacci consécutifs $F_n$ et $F_{n-1}$ tend vers le nombre d'or $\varphi=\frac{1+\sqrt{5}}{2}$ de telle sorte que la suite $u_n=\varphi-\frac{F_n}{F_{n-1}}$ soit alternativement positive et négative.\par\nobreak -\begin{lstlisting} -\STautoround{9} -$\begin{spreadtab}{{array}{ccN39N{3}{9}}} -@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline -\color{red}:=1 & \color{red}:=1 & & \\ -\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ - & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\\hline -\end{spreadtab}$ -\end{lstlisting} -\begin{center} -\STautoround{9} -$\begin{spreadtab}{{array}{ccN39N{3}{9}}} -@n & @F_n & @\hfill{\dfrac{F_n}{F_{n-1}}}\hfill\null& @\hfill{\varphi-\dfrac{F_n}{F_{n-1}}}\hfill\null\\[2ex]\hline -\color{red}:=1 & \color{red}:=1 & & \\ -\STcopy{v}{a2+1} & \color{red}:=1 & \STcopy{v}{b3/b2} & (1+5^0.5)/2-[-1,0] \\ - & \STcopy{v}{b2+b3} & & \STcopy{v}{d!3+1-c4} \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\ - & & & \\\hline -\end{spreadtab}$ -\end{center} - -\subsection{Tableau de facturation} -Voici un tableau de facturation, où les séparateurs décimaux sont alignés dans les colonnes grâce au spécificateur de colonne \og N\fg{} du package \falseverb{numprint}. - -Ce tableau est généré par l'environnement \verb=tabularx= de façon à occuper 80\% de la largeur de la ligne. La commande \verbinline=\multicolumn= a été largement utilisée pour la mise en forme :\par\nobreak -\begin{lstlisting} -\nprounddigits2 -\let\PC\% -\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} -\newcommand\RED{\color{red}} -\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} -\hline -@D\'esignation &@\multicolumn1c{Prix U}& @\multicolumn1c{Qt\'e} & @\multicolumn1c{Prix} & @\multicolumn1c{R\'eduction} & @\textbf{\`A payer}\\\hline -@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline -@\multicolumn6c{}\\[-1.5ex]\cline{4-6}% ligne vide et on remonte un peu ! -@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ -\cline{4-6} -\end{spreadtab} -\end{lstlisting} -\begin{center} -\nprounddigits2 -\let\PC\% -\newcommand\Mystrut{\rule[-1.2ex]{0pt}{4ex}} -\newcommand\RED{\color{red}} -\begin{spreadtab}{{tabularx}{0.8\linewidth}{|>\Mystrut X>\RED N42>\RED c N42>\RED c<\PC N42|}} -\hline -@D\'esignation &@\multicolumn1c{Prix U}& @\multicolumn1c{Qt\'e} & @\multicolumn1c{Prix} & @\multicolumn1c{R\'eduction} & @\textbf{\`A payer}\\\hline -@Item 1 & 5.99 & 20 & [-2,0]*[-1,0] & $-:={20}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 2 & 12 & 7 & [-2,0]*[-1,0] & $-:={10}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 3 & 4.50 & 40 & [-2,0]*[-1,0] & $-:={35}$ & [-2,0]*(1-[-1,0]/100)\\ -@Item 4 & 650 & 2 & [-2,0]*[-1,0] & $-:={15}$ & [-2,0]*(1-[-1,0]/100)\\\hline -@\multicolumn6c{}\\[-1.5ex]\cline{4-6}% ligne vide et on remonte un peu ! -@\multicolumn1c{\Mystrut}&@\multicolumn2{r|}{\textbf{Total}}& sum(d2:[0,-2]) & \multicolumn1c{$:={round(([1,0]/[-1,0]-1)*100,0)}\PC$} & {\fontseries{b}\selectfont}:={sum(f2:[0,-2])}\\ -\cline{4-6} -\end{spreadtab} -\end{center} - -\subsection{Carré magique} -\begin{lstlisting} -\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} -\hline -\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline -2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline -4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\begin{spreadtab}{{tabular}{|*3{>{\hfill\rule[-0.4cm]{0pt}{1cm}$}m{0.7cm}<{$\hfill\null}|}}} -\hline -\color{red}:=2 & 5*b2-4*a1 & 3*a1-2*b2 \\\hline -2*a1-b2 & \color{red}:={-1} & 3*b2-2*a1 \\\hline -4*b2-3*a1 & 4*a1-3*b2 & 2*b2-a1 \\\hline -\end{spreadtab} -\end{center} - -\subsection{Pyramide additive} -Chaque nombre est la somme des deux nombres se trouvant au dessous de lui.\par\nobreak -\begin{lstlisting} -\newlength\cellsize -\setlength\cellsize{1.5cm} -\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} -\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} -\cline{4-5} -&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} -&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} -&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline -\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline -\end{spreadtab} -\end{lstlisting} -\begin{center} -\newlength\cellsize -\setlength\cellsize{1.5cm} -\newcolumntype{K}{@{}>{\rule{0pt}{2.5ex}\centering\arraybackslash$}p{\cellsize}<$@{}} -\begin{spreadtab}{{tabular}{*{8}{@{}p{.5\cellsize}@{}}}} -\cline{4-5} -&&&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&&\\\cline{3-6} -&&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&&\\\cline{2-7} -&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K}{:={[-1,1]+[1,1]}}&\multicolumn{2}{|K|}{:={[-1,1]+[1,1]}}&\\\hline -\multicolumn{2}{|K}{\color{red}:={-5}}&\multicolumn{2}{|K}{\color{red}:={3}}&\multicolumn{2}{|K}{\color{red}:={-2}}&\multicolumn{2}{|K|}{\color{red}:={-3}}\\\hline -\end{spreadtab} -\end{center} -\medskip -\parskip0pt -\begin{center} -$\star$\par -$\star\quad\star$ -\end{center} -C'est tout, j'espère que cette extension vous sera utile !\par\nobreak\medskip - -Je vous remercie d'avance de me signaler par \href{mailto:unbonpetit@openmailbox.org}{\texttt{\textbf{email}}} tout bug, toute macro-fonction à implémenter que vous pensez utile ou toute proposition d'amélioration \emph{réaliste} : il ne faut pas oublier que cette extension doit rester modeste, que \ST n'est pas excel ou calc et qu'il est impossible d'implémenter toutes les fonctionnalités avancées de ces tableurs.\par\nobreak\bigskip -Christian \textsc{Tellechea} -\end{document} \ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/spreadtab/spreadtab.sty b/Master/texmf-dist/tex/latex/spreadtab/spreadtab.sty index 661eb251946..4fd9e3137de 100644 --- a/Master/texmf-dist/tex/latex/spreadtab/spreadtab.sty +++ b/Master/texmf-dist/tex/latex/spreadtab/spreadtab.sty @@ -1,48 +1,32 @@ -% ____________________________________________________________________________ -% | | -% | | -% | spreadtab v0.4c | -% | | -% | 6 november 2014 | -% | | -% |___________________________________________________________________________| +% Ce fichier contient le code de l'extension "spreadtab" % -% This is spreadtab.sty, the code of the spreadtab package. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +\def\STname {spreadtab} % +\def\STver {0.4d} % +% % +\def\STdate {2018/01/01} % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% Copyright Christian Tellechea 2009-2014 -% email : unbonpetit@openmailbox.org -% -% The "spreadtab" package consists of the 6 following files: -% spreadtab.sty (this file) -% README -% spreadtab_doc_fr.tex, spreadtab_doc_fr.pdf (manual in french) -% spreadtab_doc_en.tex, spreadtab_doc_en.pdf (manual in english) -% -% ------------------------------------------------------------------- -% This work may be distributed and/or modified under the conditions of the -% LaTeX Project Public License, either version 1.3 of this license or (at your -% option) any later version. -% The latest version of this license is in -% -% http://www.latex-project.org/lppl.txt -% -% and version 1.3 or later is part of all distributions of LaTeX version -% 2005/12/01 or later. -% ------------------------------------------------------------------- -% This work has the LPPL maintenance status `maintained'. -% -% The Current Maintainer of this work is Christian Tellechea -% ------------------------------------------------------------------- - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%% D\'efinitions pr\'ealables %%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand\ST@ver {0.4c} -\newcommand\ST@date {2014/11/03} -\newcommand\ST@fr@date {6 novembre 2014} -\newcommand\ST@eng@date{6 november 2014} - -\ProvidesPackage{spreadtab}[\ST@date\space v\ST@ver\space Spreadsheet features for table environments] +% -------------------------------------------------------------------- +% Author : Christian Tellechea +% Status : Maintained +% Email : unbonpetit@netc.fr +% Package URL: https://www.ctan.org/pkg/spreadtab +% Bug tracker: https://framagit.org/unbonpetit/spreadtab/issues +% Repository : https://framagit.org/unbonpetit/spreadtab/tree/master +% Copyright : Christian Tellechea 2009-2018 +% Licence : Released under the LaTeX Project Public License v1.3c +% or later, see http://www.latex-project.org/lppl.txt +% Files : 1) spreadtab.sty +% 2) spreadtab-fr.tex +% 3) spreadtab-fr.pdf +% 4) spreadtab-en.tex +% 5) spreadtab-en.pdf +% 6) README +% -------------------------------------------------------------------- +\ProvidesPackage{spreadtab}[\STdate\space v\STver\space Spreadsheet features for table environments (CT)] \NeedsTeXFormat{LaTeX2e} \RequirePackage{fp}% pour les calculs scientifiques \RequirePackage{xstring}[2013/07/29]% version n\'ecessaire @@ -60,113 +44,106 @@ \AtBeginDocument{\@ifpackageloaded{colortbl}\ST@colortblloadedtrue\ST@colortblloadedfalse} % D\'efinit le marqueur qui signale le commencement du champ num\'erique -\newcommand*\STnumericfieldmarker{:=} +\def\STnumericfieldmarker{:=} % D\'efinit la macro qui va afficher les valeurs num\'eriques dans le tableau -\newcommand\STprintnum[1]{#1} +\def\STprintnum#1{#1} % D\'efinit les caract\`eres entre lesquels doivent entre envelopp\'ees les r\'ef\'erences des cellules % que l'on veut afficher dans les champs textuels -\newcommand*\STsetdisplaymarks[2]{% - \def\ST@startdisplay{#1}\def\ST@enddisplay{#2}% -} +\def\STsetdisplaymarks#1#2{\def\ST@startdisplay{#1}\def\ST@enddisplay{#2}} \STsetdisplaymarks{<<}{>>}% d\'elimiteurs par d\'efaut % d\'efinit le marqueur qui signale une cellule de texte -\makeatother\newcommand*\STtextcell{@}\makeatletter +\edef\STtextcell{\string @} % Commande qui permet \'a l'utilisateur de d\'efinir le caract\`ere qui conserve une r\'ef\'erence lors de la copie d'une formule -\AtBeginDocument{\newcommand*\STtransposecar{!}} +\AtBeginDocument{\def\STtransposecar{!}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Messages d'erreur %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newif\ifST@message -\def\ST@package@name{spreadtab} - -\newcommand*\STmessage[1]{% #1 = true ou false pour autoriser ou pas les messages - \csname ST@message#1\endcsname -} +\def\STmessage#1{\csname ST@message#1\endcsname} -\newcommand*\ST@emit@message[1]{\ifST@message\message{#1}\fi} +\def\ST@emit@message#1{\ifST@message\message{#1}\fi} -\newcommand*\ST@seedoc@i{Please, read the manual.} +\def\ST@seedoc@i{Please, read the manual.} -\newcommand*\ST@circular@reference{% +\def\ST@circular@reference{% \ST@coord@toref\ST@coord \let\ST@deptree\@empty \ST@show@dependance@tree - \PackageError\ST@package@name{circular reference found in cell \ST@coord!^^J - Here is its dependant cells: \ST@deptree}\ST@seedoc@i\stop + \PackageError\STname{circular reference found in cell \ST@coord!^^J + Here is its dependant cells: \ST@deptree}\ST@seedoc@i } -\newcommand*\ST@undefined@cell{% +\def\ST@undefined@cell{% \ST@coord@toref\ST@temp@callcell \ST@coord@toref\ST@coord - \PackageError\ST@package@name{Undefined reference!^^J - Cell \ST@temp@callcell\space contains a reference to an undefined cell: \ST@coord}\ST@seedoc@i\stop + \PackageError\STname{Undefined reference!^^J + Cell \ST@temp@callcell\space contains a reference to an undefined cell: \ST@coord}\ST@seedoc@i } -\newcommand*\ST@zerocodecell@cell{% +\def\ST@zerocodecell@cell{% \ST@coord@toref\ST@temp@callcell \ST@coord@toref\ST@coord - \PackageError\ST@package@name{A reference to a non-numeric or empty cell is not allowed!^^J - Cell \ST@temp@callcell\space contains a reference to an empty or text cell: \ST@coord}\ST@seedoc@i\stop + \PackageError\STname{A reference to a non-numeric or empty cell is not allowed!^^J + Cell \ST@temp@callcell\space contains a reference to an empty or text cell: \ST@coord}\ST@seedoc@i } -\newcommand*\ST@multicol@cell{% +\def\ST@multicol@cell{% \ST@coord@toref\ST@temp@callcell \ST@coord@toref\ST@coord - \PackageError\ST@package@name{Cell \ST@temp@callcell\space contains a reference to a merged \string\multicolumn\space cell: \ST@coord}\ST@seedoc@i + \PackageError\STname{Cell \ST@temp@callcell\space contains a reference to a merged + \string\multicolumn\space cell: \ST@coord}\ST@seedoc@i } -\newcommand*\ST@illegal@relativeref{% +\def\ST@illegal@relativeref{% \edef\ST@temp@callcell{\ST@current@colnumber,\ST@current@rownumber}% \ST@coord@toref\ST@temp@callcell - \PackageError\ST@package@name{Illegal relative reference found in cell \ST@temp@callcell!}\ST@seedoc@i\stop + \PackageError\STname{Illegal relative reference found in cell \ST@temp@callcell!}\ST@seedoc@i } -\newcommand*\ST@illegal@ref{% - \PackageError\ST@package@name{Illegal reference in \string\STsavecell!}\ST@seedoc@i -} +\def\ST@illegal@ref{\PackageError\STname{Illegal reference in \string\STsavecell!}\ST@seedoc@i} -\newcommand*\ST@unmatch@matrixdim{% +\def\ST@unmatch@matrixdim{% \edef\ST@temp@callcell{\ST@current@colnumber,\ST@current@rownumber}% \ST@coord@toref\ST@temp@callcell - \PackageError\ST@package@name{Somprod dimension of matrix do not match in cell \ST@temp@callcell!}\ST@seedoc@i + \PackageError\STname{Somprod dimension of matrix do not match in cell \ST@temp@callcell!}\ST@seedoc@i } -\newcommand*\ST@fact@outofrange{% - \PackageError\ST@package@name{Argument of fact is not integer or is out of range!}\ST@seedoc@i -} +\def\ST@fact@outofrange{\PackageError\STname{Argument of fact is not integer or is out of range!}\ST@seedoc@i} -\newcommand\ST@invalid@date{% +\def\ST@invalid@date{% \edef\ST@temp@callcell{\ST@current@colnumber,\ST@current@rownumber}% \ST@coord@toref\ST@temp@callcell - \PackageError\ST@package@name{Invalid date in cell \ST@temp@callcell.}\ST@seedoc@i + \PackageError\STname{Invalid date in cell \ST@temp@callcell.}\ST@seedoc@i } -\newcommand*\ST@invalid@range{% +\def\ST@invalid@range{% \edef\ST@temp@callcell{\ST@current@colnumber,\ST@current@rownumber}% \ST@coord@toref\ST@temp@callcell - \PackageError\ST@package@name{Invalid range in cell \ST@temp@callcell.}\ST@seedoc@i\stop + \PackageError\STname{Invalid range in cell \ST@temp@callcell.}\ST@seedoc@i } -\newcommand*\ST@invalidSTcopy{% +\def\ST@invalidSTcopy{% \edef\ST@temp@callcell{\ST@current@colnumber,\ST@current@rownumber}% \ST@coord@toref\ST@temp@callcell - \PackageError\ST@package@name{Numeric field marker found, \string\STcopy\space forbidden in cell \ST@temp@callcell.}\ST@seedoc@i\stop + \PackageError\STname{Numeric field marker found, \string\STcopy\space forbidden in cell \ST@temp@callcell.}\ST@seedoc@i } -\newcommand*\ST@unknown@tag{% +\def\ST@unknown@tag{% \edef\ST@temp@callcell{\ST@current@colnumber,\ST@current@rownumber}% \ST@coord@toref\ST@temp@callcell - \PackageError\ST@package@name{Undefined tag in cell \ST@temp@callcell.}\ST@seedoc@i + \PackageError\STname{Undefined tag in cell \ST@temp@callcell.}\ST@seedoc@i } +\def\ST@intarg@required{\PackageError\STname{Macro function randint require integer argument}\ST@seedoc@i} + % transforme la chaine de cellules "(1,3)(4,5)(3,2)(1,3)" rencontr\'e en r\'ef\'erence circulaire en "A3-D5-C2-A3" -\newcommand*\ST@show@dependance@tree{% +\def\ST@show@dependance@tree{% \ST@between\ST@dependance@tree()\ST@currentref \ST@right\ST@dependance@tree)\ST@dependance@tree \ST@coord@toref\ST@currentref @@ -178,92 +155,88 @@ } % transforme la s\'equence de contr\^ole #1 qui contient par exemple «4,5» en «D5» -\newcommand*\ST@coord@toref[1]{% +\def\ST@coord@toref#1{% \ST@split#1,\ST@temp@a#1% \edef#1{\ifcase\ST@temp@a\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M\or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\fi#1}% } -\newcommand*\ST@illegal@copy{% - \PackageError\ST@package@name{Illegal reference in copied formula!}\ST@seedoc@i -} +\def\ST@illegal@copy{\PackageError\STname{Illegal reference in copied formula!}\ST@seedoc@i} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%% Macros d'affectation et d'expansion %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand*\ST@letname[1]{\expandafter\let\csname#1\endcsname} +\def\ST@letname#1{\expandafter\let\csname#1\endcsname} -\newcommand\ST@exp@two@args[3]{% +\def\ST@exp@two@args#1#2#3{% \def\ST@tmp@{#1}% \ST@expadd@tomacro\ST@tmp@{\expandafter{#2}}% \ST@expadd@tomacro\ST@tmp@{\expandafter{#3}}% \ST@tmp@ } -\newcommand\ST@add@tomacro[2]{\expandafter\def\expandafter#1\expandafter{#1#2}} +\def\ST@add@tomacro#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} -\newcommand\ST@expadd@tomacro[2]{\expandafter\ST@add@tomacro\expandafter#1\expandafter{#2}} +\def\ST@expadd@tomacro#1#2{\expandafter\ST@add@tomacro\expandafter#1\expandafter{#2}} -\newcommand\ST@edefadd@tomacro[2]{% - \edef#1{\unexpanded\expandafter{#1}#2}% -} +\def\ST@edefadd@tomacro#1#2{\edef#1{\unexpanded\expandafter{#1}#2}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%% Macros de manipulation de chaines %%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\ST@gobble@remain{% +\def\ST@gobble@remain{% mange tous jusqu'à \ST@nil. Méthode LENTE privilégiée car il peut y avoir des ) de catcode 2 isolées \afterassignment\ST@gobble@remain@i \let\ST@toks= } +\def\ST@gobble@remain@i{\unless\ifx\ST@toks\ST@nil\expandafter\ST@gobble@remain\fi} -\def\ST@gobble@remain@i{% - \unless\ifx\ST@toks\ST@nil\expandafter\ST@gobble@remain\fi -} - -\newcommand\ST@splitatfirstcar[3]{% +\def\ST@splitatfirstcar#1#2#3{% \def\ST@splitatfirstcar@i##1##2\@nil{\def#2{##1}\def#3{##2}}% \expandafter\ST@splitatfirstcar@i#1\@nil } % dans la sc #1, remplace le . par le s\'eparateur d\'ecimal -\newcommand\ST@substdecsep[1]{% - \ST@Ifinstr#1.{\expandafter\ST@substdecsep@i\expandafter#1\expandafter{\ST@decsep}}\relax +\def\ST@substdecsep#1{% + \ST@Ifinstr#1. + {\expandafter\ST@substdecsep@i\expandafter#1\expandafter{\ST@decsep}} + {}% } -\newcommand\ST@substdecsep@i[2]{% +\def\ST@substdecsep@i#1#2{% \def\ST@substdecsep@ii##1.##2\@nil{\def#1{##1#2##2}}% \expandafter\ST@substdecsep@ii#1\@nil } % enl\`eve tous les espaces de la sc #1 et assigne le r\'esultat \'a #1 -\newcommand\ST@remove@first@spaces[1]{% +\def\ST@remove@firST@spaces#1{% \IfBeginWith#1\space - {\StrGobbleLeft#11[#1]\ST@remove@first@spaces{#1}}% + {\StrGobbleLeft#11[#1]\ST@remove@firST@spaces{#1}}% {}% } -\newcommand\ST@keep@firstcar[1]{% on ne garde dans la sc #1 que le 1er caract\`ere de la sc #1 ou on enl\`eve les accolades - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\@car#1\@nil}% +\def\ST@keep@firstcar#1{% on ne garde dans la sc #1 que le 1er caract\`ere de la sc #1 ou on enl\`eve les accolades + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#1\expandafter\expandafter\expandafter{\expandafter\@car#1\@nil}% } -\newcommand\ST@firstarg@after[3]{% assigne \'a la sc #3 l'argument qui suit #2 dans le d\'eveloppement de la sc #1 +\def\ST@firstarg@after#1#2#3{% assigne \'a la sc #3 l'argument qui suit #2 dans le d\'eveloppement de la sc #1 \def\ST@firstarg@after@i##1#2##2##3\@nil{\def#3{##2}}% \expandafter\ST@firstarg@after@i#1\@nil } -\newcommand\ST@thirdarg@after[3]{% assigne \'a la sc #3 le 3\`e argument qui suit #2 dans le d\'eveloppement de la sc #1 +\def\ST@thirdarg@after#1#2#3{% assigne \'a la sc #3 le 3\`e argument qui suit #2 dans le d\'eveloppement de la sc #1 \def\ST@thirdarg@after@i##1#2##2##3##4##5\@nil{\def#3{##4}}% \expandafter\ST@thirdarg@after@i#1\@nil } % est ce que la sc #1 contient la sc #2 ? -\newcommand\ST@Ifinstr[2]{\ST@exp@two@args\ST@Ifinstr@i{#1}{#2}} -\newcommand\ST@Ifinstr@i[2]{% +\def\ST@Ifinstr#1#2{\ST@exp@two@args\ST@Ifinstr@i{#1}{#2}} +\def\ST@Ifinstr@i#1#2{% \def\ST@Ifinstr@ii##1#2##2\@nil{\ifx\@empty##2\@empty\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi}% \ST@Ifinstr@ii#1\@@nil#2\@nil } % Est ce que la sc #1 commence par les caract\`eres #2 ? -\newcommand\ST@Iffirstis[2]{% +\def\ST@Iffirstis#1#2{% \expandafter\ST@Ifinstr@i\expandafter{#1}{#2}% {\def\ST@Iffirstis@i##1#2##2\@nil{% \ifx\@empty##1\@empty\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi @@ -275,55 +248,57 @@ % Coupe la sc #1 au caract\`ere #2 % ce qui est avant est assign\'e \'a #3 et ce qui est apr\`es \'a #4 -\newcommand\ST@split[4]{% +\def\ST@split#1#2#3#4{% \def\ST@split@i##1#2##2\@nil{\def#3{##1}\def#4{##2}}% \expandafter\ST@split@i#1\@nil } % Dans la sc #1, assigne ce qui est avant le d\'eveloppement de la sc #2 \'a la sc #3 -\newcommand\ST@left[3]{\ST@exp@two@args\ST@left@i{#1}{#2}#3} -\newcommand\ST@left@i[3]{% +\def\ST@left#1#2#3{\ST@exp@two@args\ST@left@i{#1}{#2}#3} +\def\ST@left@i#1#2#3{% \def\ST@left@ii##1#2##2\@nil{\def#3{##1}}% \ST@left@ii#1\@nil } % Dans la sc #1, assigne ce qui est apr\`es le d\'eveloppement de la sc #2 \'a la sc #3 -\newcommand\ST@right[3]{\ST@exp@two@args\ST@right@i{#1}{#2}#3} -\newcommand\ST@right@i[3]{% +\def\ST@right#1#2#3{\ST@exp@two@args\ST@right@i{#1}{#2}#3} +\def\ST@right@i#1#2#3{% \def\ST@right@ii##1#2##2\@nil{\def#3{##2}}% \ST@right@ii#1\@nil } % Dans la sc #1, assigne \'a la sc #4 ce qui est entre les caract\`eres #2 et #3 -\newcommand\ST@between[4]{% +\def\ST@between#1#2#3#4{% \def\ST@between@i##1#2##2#3##3\@nil{\def#4{##2}}% \expandafter\ST@between@i#1\@nil } % Dans la sc #1, substitue la premi\`ere occurrence du pattern #2 par le pattern #3 -\newcommand\ST@subst@once[3]{% - \def\ST@subst@once@i##1#2##2\@nil{\def#1{##1#3##2}}% - \ST@Ifinstr#1{\@empty#2}{\expandafter\ST@subst@once@i#1\@nil}\relax +\def\ST@subST@once#1#2#3{% + \def\ST@subST@once@i##1#2##2\@nil{\def#1{##1#3##2}}% + \ST@Ifinstr#1{\@empty#2} + {\expandafter\ST@subST@once@i#1\@nil} + {}% } % Dans la sc #1, substitue le pattern #2 par le pattern #3 -\newcommand\ST@subst[3]{% - \def\ST@subst@i##1#2##2\@nnil{% +\def\ST@subst#1#2#3{% + \def\ST@subST@i##1#2##2\@nnil{% \ifx\@empty##2\@empty \def#1{##1}\expandafter\remove@to@nnil \else - \expandafter\ST@subst@i + \expandafter\ST@subST@i \fi ##1#3##2\@nnil }% - \expandafter\ST@subst@i#1#2\@nnil + \expandafter\ST@subST@i#1#2\@nnil } -\newcommand\ST@expsubst[3]{\ST@exp@two@args{\ST@subst#1}{#2}{#3}} +\def\ST@expsubst#1#2#3{\ST@exp@two@args{\ST@subst#1}{#2}{#3}} -\newcommand\ST@removespaces[1]{\ST@subst#1{ }{}} +\def\ST@removespaces#1{\ST@subst#1{ }{}} -\newcommand\ST@ifvalid@csname[1]{% +\def\ST@ifvalid@csname#1{% \ifcsname#1\endcsname \expandafter\ifx\csname#1\endcsname\ST@undef@content \expandafter\expandafter\expandafter\@secondoftwo @@ -339,14 +314,14 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Lecture du tableau %%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % lit le tableau : consid\`ere que \\ s\'epare les lignes -\newcommand\ST@read@tab{% +\def\ST@read@tab{% \def\ST@total@colnumber{0}% \ST@rowcount\z@ \ST@search@hline% on met de c\^ot\'e la (ou les) ligne sup\'erieure du tableau \ST@read@tab@i } -\newcommand\ST@read@tab@i{% +\def\ST@read@tab@i{% \advance\ST@rowcount\@ne \ST@Ifinstr\ST@tab{\ST@eol}% si contient \\, il reste encore des lignes {\expandafter\ST@split\expandafter\ST@tab\expandafter{\ST@eol}\ST@current@row\ST@tab @@ -354,11 +329,11 @@ \ST@Iffirstis\ST@tab[% on prend en compte l'\'eventuel argument optionnel de \\ {\ST@between\ST@tab[]\ST@temp@a% prend ce qui est entre crochet \ST@Ifinstr\ST@temp@a,% si c'est une r\'ef\'erence (on teste juste la pr\'esence de la virgule, ça devrait suffire) - \relax% on ne fait rien + {}% on ne fait rien {\ST@split\ST@tab]\ST@temp@a\ST@tab% sinon, coupe au crocher fermant \expandafter\ST@expadd@tomacro\csname endrow@\number\ST@rowcount\endcsname{\ST@temp@a]}}% ajoute l'argument optionnel \'a la fin de ligne }% - \relax + {}% \ST@search@hline% on va purger les hlines et les mettre dans la fin de ligne \ifx\ST@tab\@empty \let\ST@next@readrows\relax @@ -374,7 +349,7 @@ {\edef\ST@row@skiplist{(\number\ST@rowcount)\ST@row@skiplist}% on ajoute le num\'ero de ligne \'a masquer \'a la skiplist \StrDel\ST@current@row{\@empty\SThiderow}[\ST@current@row]% }% - \relax + {}% \ST@colcount\z@ \let\ST@multicol@number\@empty \let\ST@nextcell\@empty @@ -382,29 +357,31 @@ \ST@next@readrows } -\newcommand\ST@read@cells{% divise la ligne contenue dans \ST@current@row en cellules +\def\ST@read@cells{% divise la ligne contenue dans \ST@current@row en cellules \advance\ST@colcount\@ne \ST@Ifinstr\ST@current@row&% {\ST@split\ST@current@row&\ST@current@cell\ST@current@row - \let\ST@next@readcells\ST@read@cells}% + \let\ST@next@readcells\ST@read@cells + }% {\let\ST@current@cell\ST@current@row \let\ST@next@readcells\relax - \ifnum\ST@colcount>\ST@total@colnumber\edef\ST@total@colnumber{\number\ST@colcount}\fi}% + \ifnum\ST@colcount>\ST@total@colnumber\edef\ST@total@colnumber{\number\ST@colcount}\fi + }% \ST@Ifinstr\ST@current@cell{\@empty\SThidecol}% on doit masquer cette colonnes ? {\ST@Ifinstr\ST@col@skiplist{\expandafter(\number\ST@colcount)}% ça a d\'ej\'a \'et\'e demand\'e ? - \relax% on fait rien + {}% on fait rien {\edef\ST@col@skiplist{(\number\ST@colcount)\ST@col@skiplist}% sinon -> ajout \'a la skiplist - \ifnum\ST@colcount>\ST@last@skipcol\edef\ST@last@skipcol{\number\ST@colcount}\fi + \ifnum\ST@colcount>\ST@laST@skipcol\edef\ST@laST@skipcol{\number\ST@colcount}\fi }% \StrDel\ST@current@cell{\@empty\SThidecol}[\ST@current@cell]% }% - \relax + {}% \exploregroups \ST@Ifinstr\ST@current@cell{\@empty\multicolumn}% tester la pr\'esence d'un \multicol {\ST@firstarg@after\ST@current@cell\multicolumn\ST@multicol@number}% {\let\ST@multicol@number\@empty}% \IfSubStr\ST@current@cell\STnumericfieldmarker% il y a un marqueur de champ num\'erique ? - {\IfSubStr\ST@current@cell{\@empty\STcopy}\ST@invalidSTcopy\relax% s'il y a un \STcopy, erreur (pas de champ num\'erique et de \STcopy dans une m\^eme cellule) + {\IfSubStr\ST@current@cell{\@empty\STcopy}\ST@invalidSTcopy{}% s'il y a un \STcopy, erreur (pas de champ num\'erique et de \STcopy dans une m\^eme cellule) \StrBehind\ST@current@cell\STnumericfieldmarker[\ST@current@formula]% \noexploregroups \StrChar\ST@current@formula1[\ST@temp@a]% \ST@temp@a contient {\z@% si ce nombre est plus grand que 0 -> r\'ef\'erence valide \let\ST@temp@formula\@xs@afterinteger% on prend ce qui est apr\`es le nombre \expandafter\lowercase\expandafter{\expandafter\def\expandafter\ST@firstcar\expandafter{\ST@firstcar}}% met en minuscules @@ -617,7 +594,7 @@ % Cherche dans la sc #1 les 3 arguments qui se trouvent apr\`es \STcopy % Affecte le 1er \'a #2, le 2\`e \'a #3 et le 3\`e \'a #4 -\newcommand\ST@findcopyargs[3]{% +\def\ST@findcopyargs#1#2#3{% \def\ST@argaftercopy##1\STcopy##2##3##4\@nil{% \def#1{##1}\ST@expadd@tomacro#1{\STnumericfieldmarker##4}% dans #1,supprime \STcopy{}{} et le remplace par := \def#2{##2}\def#3{##3}% @@ -668,21 +645,21 @@ % Regarde dans la liste de copie si la cellule de coodonn\'ees #1 #2 est dans une plage de copie % si oui, affecte \'a #3 la formule transpos\'ee % La liste de copy est parcourue de gauche \'a droite avec sortie d\`es qu'une plage qui convient est rencontr\'ee -\newcommand\ST@lookincopylist[3]{% +\def\ST@lookincopylist#1#2#3{% \let\ST@alias@copylist\ST@copylist \let\ST@returnedformula\@empty \def\ST@copycol{#1}\def\ST@copyrow{#2}\let#3\@empty - \ST@lookincopylist@i + \ST@lookincopyliST@i \let#3\ST@returnedformula } -\newcommand\ST@lookincopylist@i{% +\def\ST@lookincopyliST@i{% \expandafter\ST@testfirstincopylist\ST@alias@copylist\@nil \ifx\@empty\ST@alias@copylist \let\ST@next\relax \else \ifx\@empty\ST@returnedformula - \let\ST@next\ST@lookincopylist@i + \let\ST@next\ST@lookincopyliST@i \else \let\ST@next\relax \fi @@ -691,8 +668,7 @@ } % Teste si un \'el\'ement de la copylist contient une plage qui inclus la cellule en cours. -\def\ST@testfirstincopylist|#1|[#2,#3](#4,#5)#6\@nil% -{% +\def\ST@testfirstincopylist|#1|[#2,#3](#4,#5)#6\@nil{% \def\ST@alias@copylist{#6}% on enl\`eve le premier \'el\'ement de la copylist \ST@Ifin\ST@copycol\ST@copyrow[#2,#3](#4,#5)% si ça correspond {\def\ST@returnedformula{#1}% @@ -711,7 +687,7 @@ % S'il trouve > ou v sans nombre derri\`ere, le d\'ecalage correspondant est vide % S'il ne trouve pas > ou v, le d\'ecalage correspond est \'egal \'a 0 % Assigne les d\'ecalages trouv\'es dans \ST@hoffest et \ST@voffest -\newcommand\ST@seekcopyoffset[1]{% +\def\ST@seekcopyoffset#1{% \ST@Ifinstr#1>% {\ST@findcopyoffest#1>\ST@hoffest}% {\def\ST@hoffest{0}}% @@ -721,54 +697,46 @@ } % Cherche dans la sc #1 ce qui est entre #2 et , -\newcommand\ST@findcopyoffest[3]{% - \def\ST@findcopyoffest@i##1#2##2,##3\@nil{\def#3{##2}}% - \expandafter\ST@findcopyoffest@i#1,\@nil +\def\ST@findcopyoffest#1#2#3{% + \def\ST@findcopyoffeST@i##1#2##2,##3\@nil{\def#3{##2}}% + \expandafter\ST@findcopyoffeST@i#1,\@nil } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%% Recherche d'une r\'ef\'erence %%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % teste si le token #1 est une lettre (majuscule ou minuscule) -\newcommand\ST@ifcar@isletter[1]{% - \ifcat\relax\noexpand#1 - \let\ST@next\@secondoftwo% faux si c'est une sc - \else - \ifnum`#1<\ifnum`#1<`a`A\else`a\fi - \let\ST@next\@secondoftwo - \else - \ifnum`#1>\ifnum`#1<`a`Z\else`z\fi - \let\ST@next\@secondoftwo - \else - \let\ST@next\@firstoftwo - \fi - \fi - \fi - \ST@next +\def\ST@ifcar@isletter#1{% + \begingroup\escapechar`\\ + \lowercase{\expandafter\ST@ifcar@isletter@i\detokenize{#1}}.\@nil +} +\def\ST@ifcar@isletter@i#1#2\@nil{% + \endgroup + \ifnum\numexpr(`#1-`a)*(`#1-`z)\relax>\z@\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi } % cherche une r\'ef\'erence du type lettre+nombre dans la sc #1 % si on trouve, renvoie les coordonn\'ees dans #2 sous la forme x@y % si on ne trouve pas, #2 est vide. -\newcommand\ST@findref@informula[2]{% +\def\ST@findref@informula#1#2{% \let\ST@temp@formula#1% \ST@findref@informula@i \let#2\ST@temp@formula \unless\ifx\@empty\ST@ref@found - \ST@Iffirstis\ST@after@ref@found|\relax{% - \ST@exp@two@args{\ST@subst@once#1}\ST@ref@found{\ST@ref@found|}% - }% + \ST@Iffirstis\ST@after@ref@found| + {} + {\ST@exp@two@args{\ST@subST@once#1}\ST@ref@found{\ST@ref@found|}}% \fi } -\newcommand\ST@findref@informula@i{% +\def\ST@findref@informula@i{% \let\ST@next@search\ST@findref@informula@i \ifx\@empty\ST@temp@formula \let\ST@next@search\relax \else \StrSplit\ST@temp@formula1\ST@firstcar\ST@temp@formula% prend le 1er car de ce qui reste \expandafter\ST@ifcar@isletter\expandafter{\ST@firstcar}% est-ce que le 1er car est une lettre ? - {\IfInteger\ST@temp@formula\relax\relax% on prend le nombre qui suit + {\IfInteger\ST@temp@formula{}{}% on prend le nombre qui suit \ifnum\integerpart>\z@% si ce nombre est plus grand que 0 -> r\'ef\'erence valide \let\ST@after@ref@found\@xs@afterinteger \edef\ST@ref@found{\ST@firstcar\number\integerpart}% est la r\'ef\'erence trouv\'ee @@ -802,7 +770,7 @@ } % cette commande teste si la sc #1 est syntaxiquement une r\'ef\'erence -\newcommand\ST@ifref[1]{% +\def\ST@ifref#1{% \let\ST@temp@formula#1% \let\ST@ref@found\@empty \ST@findref@informula@i @@ -822,28 +790,28 @@ %%%%%%%%%%%%%%%%% Le noyau : \'evaluation de toutes les cellules %%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Essaie de calculer la cellule (#1,#2) -\def\ST@try@calc@cell(#1,#2)% -{% +\def\ST@try@calc@cell(#1,#2){% \ST@ifvalid@csname{formula@#1@#2}% on v\'erifie que la formule existe {\expandafter\ifx\csname formula@#1@#2\endcsname\@empty \@namedef{code@#1@#2}{0}% si vide, code \'a 0 \else% et qu'elle est non vide \def\ST@current@colnumber{#1}\def\ST@current@rownumber{#2}% - \expandafter\ST@find@first@func\csname formula@#1@#2\endcsname% cherche une fonction dans la formule + \expandafter\ST@find@firST@func\csname formula@#1@#2\endcsname% cherche une fonction dans la formule \ifx\@empty\ST@function@namefound% s'il n'y a pas de fonction \expandafter\ST@findref@informula\csname formula@#1@#2\endcsname\ST@coord \ifx\@empty\ST@coord% ni de r\'ef\'erence \ST@calc@cell(#1,#2)% on va la calculer la cellule \fi \fi - \fi}\relax + \fi + } + {}% } -\def\ST@calc@cell(#1,#2)% -{% calcule la formule num\'erique de la cellule (#1,#2) +\def\ST@calc@cell(#1,#2){% calcule la formule num\'erique de la cellule (#1,#2) \unless\ifnum\csname code@#1@#2\endcsname<\@ne% si le code est >= 1 \expandafter\let\expandafter\ST@temp@a\csname formula@#1@#2\endcsname% \ST@temp@a est le contenu de la formule - \ST@Iffirstis\ST@temp@a-{\expandafter\def\expandafter\ST@temp@a\expandafter{\expandafter0\ST@temp@a}}\relax + \ST@Iffirstis\ST@temp@a-{\expandafter\def\expandafter\ST@temp@a\expandafter{\expandafter0\ST@temp@a}}{}% \FPeval\ST@temp@a\ST@temp@a% on calcule cette formule \unless\ifx\ST@rounddigit\@empty\FPround\ST@temp@a\ST@temp@a\ST@rounddigit\fi% on arrondi s'il faut \ifST@clipround% on arrondit en enlevant les 0 inutiles ? @@ -859,18 +827,18 @@ } % Calcule toutes les formules du tableau -\newcommand\ST@eval@tab{% +\def\ST@eval@tab{% \ST@rowcount\@ne\ST@colcount\@ne \ST@eval@tab@i } -\newcommand\ST@eval@tab@i{% +\def\ST@eval@tab@i{% \ifnum\ST@rowcount>\ST@total@rownumber \let\ST@nextcell\relax \else \ST@ifvalid@csname{formula@\number\ST@colcount @\number\ST@rowcount}% si la formule existe {\ST@eval@cell(\number\ST@colcount,\number\ST@rowcount)}% on la calcule - \relax + {}% \advance\ST@colcount\@ne \let\ST@nextcell\ST@eval@tab@i \ifnum\ST@colcount>\ST@total@colnumber @@ -884,7 +852,7 @@ % la sc #1 est le nom d'une fonction. % La macro renvoie dans la sc #2 : 1, 2 ou 2 selon que #1 est le nom d'une macro \'a argument num\'erique, \'a argument plage ou \'a argument texte. % #2 est vaut 0 si #1 n'est pas le nom d'une fonction -\newcommand\ST@determine@function@code[2]{% +\def\ST@determine@function@code#1#2{% \ST@Ifinstr{\ST@functions@with@num@arg,}{#1,}% {\def#2{1}}% {\ST@Ifinstr{\ST@functions@with@range@arg,}{#1,}% @@ -897,9 +865,8 @@ } % \'Evalue la cellule (#1#2) par ses coordonn\'ees num\'eriques (col,row) -\def\ST@eval@cell(#1,#2)% -{% - \def\ST@dependance@tree{(#1,#2)}% +\def\ST@eval@cell(#1,#2){% + \edef\ST@dependance@tree{(#1,#2)}% FIXME : mettre \edef \let\ST@stackcall\@empty \let\ST@function@namesaved\@empty \ST@eval@cell@i(#1,#2)% on appelle la macro r\'ecursive @@ -912,15 +879,14 @@ } % Ceci est la macro principale : elle \'evalue la cellule (#1,#2) -\def\ST@eval@cell@i(#1,#2)% #1 = no colonne #2 = no ligne -{% +\def\ST@eval@cell@i(#1,#2){% #1 = no colonne #2 = no ligne \ifnum\csname code@#1@#2\endcsname=\@ne% on ne fait quelque chose que si le code est 1 : cellule non calcul\'ee \def\ST@current@colnumber{#1}\def\ST@current@rownumber{#2}% - \expandafter\ST@find@first@func\csname formula@#1@#2\endcsname% cherche une fonction dans la formule + \expandafter\ST@find@firST@func\csname formula@#1@#2\endcsname% cherche une fonction dans la formule \ifx\@empty\ST@function@namefound% il n'y a pas de fonction \IfSubStr[2]\ST@dependance@tree{(#1,#2)}% {\edef\ST@coord{#1,#2}\ST@circular@reference}% message et on s'arr\^ete si r\'ef\'erence circulaire - \relax + {}% \expandafter\ST@findref@informula\csname formula@#1@#2\endcsname\ST@coord% y a t-il une r\'ef\'erence dans l'argument ? \ifx\ST@coord\@empty% pas de r\'ef\'erence dans l'argument \ifx\ST@function@namesaved\@empty% si aucune fonction n'a \'et\'e d\'ecel\'ee @@ -954,7 +920,7 @@ % si la valeur distante est <0, on la met entre parenth\`eses \ST@Iffirstis\ST@distant@formula-% {\expandafter\def\expandafter\ST@distant@formula\expandafter{\expandafter(\ST@distant@formula)}}% - \relax + {}% % on remplace toutes les r\'ef\'erences par la valeur distante \expandafter\ST@expsubst\csname formula@#1@#2\endcsname{\ST@ref@found|}\ST@distant@formula \edef\ST@stackcall{(#1,#2)\ST@stackcall}% puis, on \'evalue \'a nouveau cette cellule @@ -972,7 +938,7 @@ \let\ST@function@namesaved\ST@function@namefound \ST@determine@function@code\ST@function@namefound\ST@codefunc% d\'etermine le code de la fonction \ifcase\ST@codefunc\relax - \PackageError\ST@package@name{This error should not occur! Please email the author. Thanks.}{}% + \PackageError\STname{This error should not occur! Please email the author. Thanks.}{}% \or% le code vaut 1, c'est une fonction \'a argument num\'erique \ST@findref@informula\ST@function@argfound\ST@temp@formula% y a t-il une r\'ef\'erence dans l'argument de la formule ? \ifx\ST@temp@formula\@empty% pas de r\'ef\'erence dans l'argument de la fonction @@ -980,10 +946,10 @@ \let\ST@tobereplaced\ST@function@namefound \ST@expadd@tomacro\ST@tobereplaced{\expandafter(\ST@function@argfound)}% ce qui va \^etre replac\'e : fonction(argument) \ST@Ifinstr{\ST@functions@no@calc@arg,}{\ST@function@namefound,}% doit-on calculer l'argument de cette fonction ? - \relax + {}% {\FPeval\ST@function@argfound\ST@function@argfound\FPclip\ST@function@argfound\ST@function@argfound}% \csname ST@func@\ST@function@namefound\endcsname\ST@function@argfound\ST@result@func% puis on \'evalue la fonctionfound - \ST@Iffirstis\ST@result@func-{\expandafter\def\expandafter\ST@result@func\expandafter{\expandafter(\ST@result@func)}}\relax + \ST@Iffirstis\ST@result@func-{\expandafter\def\expandafter\ST@result@func\expandafter{\expandafter(\ST@result@func)}}{}% \ST@expsubst\ST@current@formula\ST@tobereplaced\ST@result@func% on replace dans l'alias \ST@letname{formula@#1@#2}\ST@current@formula% on l'assigne dans la formule \ifx\@empty\ST@current@formula% pour cause de macro fonction "tag" qui est seule et qui a disparue apr\`es substitution @@ -996,7 +962,7 @@ \expandafter\let\expandafter\ST@current@formula\csname formula@\ST@temp@formula\endcsname% alias pour la formule distante \ST@Iffirstis\ST@current@formula-% {\expandafter\def\expandafter\ST@current@formula\expandafter{\expandafter(\ST@current@formula)}}% - \relax + {}% \let\ST@tobereplaced\ST@function@namefound \ST@expadd@tomacro\ST@tobereplaced{\expandafter(\ST@function@argfound)}% \let\ST@replaced\ST@tobereplaced @@ -1013,7 +979,7 @@ \let\ST@tobereplaced\ST@function@namefound\ST@expadd@tomacro\ST@tobereplaced{\expandafter(\ST@function@argfound)}% \csname ST@func@\ST@function@namefound\endcsname\ST@function@argfound\ST@result@func% puis on essaie d'\'evaluer la fonction \unless\ifx\ST@result@func\@empty% si le calcul a abouti - \ST@Iffirstis\ST@result@func-{\expandafter\def\expandafter\ST@result@func\expandafter{\expandafter(\ST@result@func)}}\relax + \ST@Iffirstis\ST@result@func-{\expandafter\def\expandafter\ST@result@func\expandafter{\expandafter(\ST@result@func)}}{}% \expandafter\ST@expsubst\csname formula@#1@#2\endcsname\ST@tobereplaced\ST@result@func% on replace dans la formule \edef\ST@stackcall{(#1,#2)\ST@stackcall}% puis, on \'evalue \'a nouveau cette cellule \fi @@ -1035,7 +1001,8 @@ \expandafter\let\expandafter\ST@current@formula\csname text@\ST@temp@formula\endcsname% alias pour la zone texte distante \StrDel[1]\ST@current@formula\STnumericfieldmarker[\ST@current@formula]% on enl\`eve le := si besoin \ST@Ifinstr\ST@current@formula{\@empty\multicolumn}% on ne prend que le texte s'il y a un \multicolumn qui traine - {\ST@thirdarg@after\ST@current@formula\multicolumn\ST@current@formula}\relax + {\ST@thirdarg@after\ST@current@formula\multicolumn\ST@current@formula} + {}% \let\ST@tobereplaced\ST@function@namefound \ST@expadd@tomacro\ST@tobereplaced{\expandafter(\ST@function@argfound)}% \ST@subst\ST@tobereplaced|{}% @@ -1043,7 +1010,7 @@ \expandafter\ST@expsubst\csname formula@#1@#2\endcsname\ST@tobereplaced\ST@result@func \edef\ST@stackcall{(#1,#2)\ST@stackcall}% puis, on \'evalue \'a nouveau cette cellule \else - \PackageError\ST@package@name{Macro function \ST@function@namefound\space requires a reference to a text cell!}\ST@seedoc@i + \PackageError\STname{Macro function \ST@function@namefound\space requires a reference to a text cell!}\ST@seedoc@i \fi \fi \fi @@ -1054,7 +1021,7 @@ % On regarde s'il y a des appels de calcul de cellules en attente % Si oui, on enl\`eve le 1er appel de la pile lifo et on l'ex\'ecute -\newcommand\ST@next@onstack{% +\def\ST@next@onstack{% \unless\ifx\ST@stackcall\@empty \ST@split\ST@stackcall)\ST@temp@a\ST@stackcall \ST@add@tomacro\ST@temp@a)% @@ -1064,12 +1031,12 @@ \fi } -\newcommand\ST@sanitize@stack{% enl\`eve de \ST@stackcall toutes les occurrences de \ST@temp@a +\def\ST@sanitize@stack{% enl\`eve de \ST@stackcall toutes les occurrences de \ST@temp@a \ST@Ifinstr\ST@stackcall\ST@temp@a {\expandafter\ST@subst\expandafter\ST@stackcall\expandafter{\ST@temp@a}{}% \ST@sanitize@stack }% - \relax + {}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1077,37 +1044,37 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % liste des fonctions dont l'argument est num\'erique -\newcommand\ST@functions@with@num@arg{% +\def\ST@functions@with@num@arg{% id,fact,ifeq,ifgt,iflt,numtofrshortdate,numtoengshortdate,numtofrlongdate,gcd,lcm,% numtoenglongdate,numtofrmonth,numtoengmonth,numtofrday,numtoengday} % liste des fonctions dont l'argument est une plage ou est vide -\newcommand\ST@functions@with@range@arg{sum,rand,randint,sumprod} +\def\ST@functions@with@range@arg{sum,rand,randint,sumprod} % liste des fonctions dont l'argument est un texte -\newcommand\ST@functions@with@text@arg{frshortdatetonum,engshortdatetonum,englongdatetonum,frlongdatetonum,scitodec,tag,row,col,cell} +\def\ST@functions@with@text@arg{frshortdatetonum,engshortdatetonum,englongdatetonum,frlongdatetonum,scitodec,tag,row,col,cell,value} % liste des fonctions dont l'argument ne doit pas \^etre calcul\'e -\newcommand\ST@functions@no@calc@arg{ifeq,ifgt,iflt,gcd,lcm} +\def\ST@functions@no@calc@arg{ifeq,ifgt,iflt,gcd,lcm,value} % liste des fonctions dont l'argument est une variable -> il ne faut donc pas aller chercher des r\'ef\'erences dans l'argument -\newcommand\ST@functions@with@assign@argument{tag,row,col,cell} +\def\ST@functions@with@assign@argument{tag,row,col,cell,value} % liste des fonctions dont le r\'esultat est un texte -\newcommand\ST@functions@with@textresult{% +\def\ST@functions@with@textresult{% numtofrshortdate,numtoengshortdate,numtofrlongdate,numtoenglongdate,% numtofrmonth,numtoengmonth,numtofrday,numtoengday} % liste totale des fonctions \edef\ST@functions@list{\ST@functions@with@range@arg,\ST@functions@with@num@arg,\ST@functions@with@text@arg} -\newcommand\ST@for[2]{% \ST@for{#1}{code} -> ex\'ecute le code pour toutes les cellules des plages pass\'ees en argument #1 +\def\ST@for#1#2{% \ST@for{#1}{code} -> ex\'ecute le code pour toutes les cellules des plages pass\'ees en argument #1 \def\ST@forcode{#2}% \expandafter\def\expandafter\ST@for@rangelist\expandafter{#1;}% \ST@for@i } -\newcommand\ST@for@loopcode{% #2 est le code \'a ex\'ecuter dans la boucle for +\def\ST@for@loopcode{% #2 est le code \'a ex\'ecuter dans la boucle for \ST@forcode% on ex\'ecute le code \let\ST@nextfor\ST@for@loopcode \advance\ST@colcount@i\@ne @@ -1122,17 +1089,17 @@ \ST@nextfor } -\newcommand\ST@for@i{% +\def\ST@for@i{% \ST@left\ST@for@rangelist;\ST@for@currentrange \ST@left{\ST@for@currentrange:}{\@empty:}\ST@temp@a - \ST@ifref\ST@temp@a\relax\ST@invalid@range + \ST@ifref\ST@temp@a{}\ST@invalid@range \let\ST@for@col@start\ST@distant@colnumber \let\ST@for@row@start\ST@distant@rownumber \ST@colcount@i\ST@distant@colnumber \ST@rowcount@i\ST@distant@rownumber \ST@Ifinstr\ST@for@currentrange{\@empty:}% {\ST@right\ST@for@currentrange{\@empty:}\ST@temp@a - \ST@ifref\ST@temp@a\relax\ST@invalid@range + \ST@ifref\ST@temp@a{}\ST@invalid@range \let\ST@for@col@end\ST@distant@colnumber \let\ST@for@row@end\ST@distant@rownumber \let\ST@nextfor\ST@for@loopcode @@ -1153,19 +1120,19 @@ % Cette macro cherche dans la sc #1 la premi\`ere fonction qu'elle trouve ne contenant pas d'autre fonction dans son argument % En sortie, \ST@function@namefound contient le nom de la fonction trouv\'ee et \ST@function@argfound son argument. % Si aucune fonction mot-cl\'e n'est trouv\'e, ces 2 derni\`eres s\'equences de contr\^oles sont vides. -\newcommand\ST@find@first@func[1]{% +\def\ST@find@firST@func#1{% \let\ST@function@namefound\@empty\let\ST@function@argfound\@empty \let\ST@function@namefound@\@empty\let\ST@function@argfound@\@empty \let\ST@tempfunc#1% - \ST@find@first@func@i + \ST@find@firST@func@i } -\newcommand\ST@find@first@func@i{% +\def\ST@find@firST@func@i{% \edef\ST@tempfunctions@list{\ST@functions@list,}% r\'einitialise la liste \let\ST@tempfunc@\ST@tempfunc% sauveagrde pour restauration ult\'erieure \let\ST@function@namefound\@empty% initialise avant appel \'a la macro \ST@Ifinstr\ST@tempfunc(% s'il y a une parenth\`ese - {\ST@find@first@func@ii% cherche la 1ere fonction dans l'argument + {\ST@find@firST@func@ii% cherche la 1ere fonction dans l'argument \ifx\ST@function@namefound\@empty% elle n'existe pas ? \let\ST@function@namefound\ST@function@namefound@\let\ST@function@argfound\ST@function@argfound@% on restaure les valeurs pr\'ec\'edentes \else% si il y a une fonction dans l'argument @@ -1173,12 +1140,12 @@ \ST@seekfunc@arg\ST@tempfunc\ST@function@argfound% isole l'argument entre parenth\`eses \let\ST@function@namefound@\ST@function@namefound\let\ST@function@argfound@\ST@function@argfound% met \'a jour les valeurs pr\'ec\'edentes \let\ST@tempfunc\ST@function@argfound% recommence avec l'argument - \expandafter\ST@find@first@func@i + \expandafter\ST@find@firST@func@i \fi}% {\let\ST@function@namefound\ST@function@namefound@\let\ST@function@argfound\ST@function@argfound@}% } -\newcommand\ST@find@first@func@ii{% +\def\ST@find@firST@func@ii{% \unless\ifx\ST@tempfunc\@empty% tant que le contenu n'est pas vide \unless\ifx\ST@tempfunctions@list\@empty% et tant que tous les noms de fonctions n'ont pas \'et\'e explor\'es \ST@split\ST@tempfunctions@list,\ST@current@funcname\ST@tempfunctions@list @@ -1186,8 +1153,8 @@ {\let\ST@function@namefound\ST@current@funcname \ST@left\ST@tempfunc{\ST@current@funcname(}\ST@tempfunc% on r\'eduit l'argument \'a ce qui est avant ce nom }% - \relax - \expandafter\expandafter\expandafter\ST@find@first@func@ii + {}% + \expandafter\expandafter\expandafter\ST@find@firST@func@ii \fi \fi } @@ -1195,24 +1162,27 @@ % la sc #1 commence normalement (sinon, ça va gueuler) par une parenth\`ese % La macro trouve l'argument se trouvant entre les parenth\`eses les plus ext\'erieures % et l'assigne \'a la sc #2 -\newcommand\ST@seekfunc@arg[2]{% +\def\ST@seekfunc@arg#1#2{% \begingroup \everyeof{\ST@nil}% met un \@nil \`a la fin du fichier virtuel \endlinechar\m@ne \catcode\z@12 \catcode`(=1 \catcode`)=2 \afterassignment\ST@gobble@remain - \expandafter\def\expandafter\ST@temp@a\scantokens\expandafter{#1}% + \expandafter\def\expandafter\ST@temp@a\scantokens\expandafter{#1}% Attentionn !!! Il peut rester des ) non équilibrées \catcode`(=12 \catcode`)=12 \def\ST@assign@result##1\ST@nil{\endgroup\def#2{##1}}% \expandafter\ST@assign@result\scantokens\expandafter{\ST@temp@a}% on fait l'assignation } -\newcommand\ST@func@sum[2]{% #1 est la sc contenant la plage de valeurs, #2 est la sc recevant le r\'esultat +\def\ST@func@sum#1#2{% #1 est la sc contenant la plage de valeurs, #2 est la sc recevant le r\'esultat \def#2{0}% r\'esultat nul pour l'instant \let\ST@temp@stack\@empty% pile d'appel temporaire vide aussi au d\'ebut \ST@for{#1}% on parcourt la - {\ifcase\csname code@\number\ST@colcount@i @\number\ST@rowcount@i\endcsname\relax% on ne prend en compte que les code 1 et 2 + {\ifnum\numexpr10000*(\ST@colcount@i-\ST@current@colnumber)+\ST@rowcount@i-\ST@current@rownumber=\z@ + \ST@invalid@range% si la cellule courante est dans la plage, erreur + \fi + \ifcase\csname code@\number\ST@colcount@i @\number\ST@rowcount@i\endcsname\relax% on ne prend en compte que les code 1 et 2 \or% code=1 \edef\ST@temp@stack{\ST@temp@stack(\number\ST@colcount@i,\number\ST@rowcount@i)}% \or% code=2 @@ -1230,15 +1200,15 @@ \fi } -\newcommand\ST@func@sumprod[2]{% #1 est la sc contenant la plage de valeurs, #2 est la sc recevant le r\'esultat +\def\ST@func@sumprod#1#2{% #1 est la sc contenant la plage de valeurs, #2 est la sc recevant le r\'esultat \ST@left{#1;};\ST@firstmat \ST@right#1;\ST@othermat \ST@left\ST@firstmat{\@empty:}\ST@temp@a - \ST@ifref\ST@temp@a\relax\ST@invalid@range + \ST@ifref\ST@temp@a{}\ST@invalid@range \let\ST@mat@firstcol\ST@distant@colnumber \let\ST@mat@firstrow\ST@distant@rownumber \StrBehind\ST@firstmat{\@empty:}[\ST@temp@a]% - \ST@ifref\ST@temp@a\relax\ST@invalid@range + \ST@ifref\ST@temp@a{}\ST@invalid@range \edef\ST@matcol{\number\numexpr\ST@distant@colnumber-\ST@mat@firstcol}% \edef\ST@matrow{\number\numexpr\ST@distant@rownumber-\ST@mat@firstrow}% \ST@count\@ne @@ -1247,13 +1217,13 @@ \ST@left{\ST@othermat;};\ST@currentmat \ST@right{\ST@othermat;};\ST@othermat \ST@left{\ST@currentmat:}{\@empty:}\ST@temp@a - \ST@ifref\ST@temp@a\relax\ST@invalid@range + \ST@ifref\ST@temp@a{}\ST@invalid@range \let\ST@currentmatcol\ST@distant@colnumber \let\ST@currentmatrow\ST@distant@rownumber \expandafter\edef\csname ST@vectorcol@\romannumeral\ST@count\endcsname{\number\numexpr\ST@distant@colnumber-\ST@mat@firstcol}% \expandafter\edef\csname ST@vectorrow@\romannumeral\ST@count\endcsname{\number\numexpr\ST@distant@rownumber-\ST@mat@firstrow}% \ST@right\ST@currentmat{\@empty:}\ST@temp@a - \ST@ifref\ST@temp@a\relax\ST@invalid@range + \ST@ifref\ST@temp@a{}\ST@invalid@range \edef\ST@currentmatcol{\number\numexpr\ST@distant@colnumber-\ST@currentmatcol}% \edef\ST@currentmatrow{\number\numexpr\ST@distant@rownumber-\ST@currentmatrow}% \unless\ifnum\ST@matcol=\ST@currentmatcol\ST@unmatch@matrixdim\fi% la dimension horizontale ne correspond pas @@ -1299,10 +1269,10 @@ \fi } -\newcommand\ST@func@id[2]{\expandafter\def\expandafter#2\expandafter{#1}} +\def\ST@func@id#1#2{\expandafter\def\expandafter#2\expandafter{#1}} % Calcule la factorielle du nombre #1 et met le r\'esultat dans la sc #2 -\newcommand\ST@func@fact[2]{% +\def\ST@func@fact#1#2{% \FPifint{#1}% \FPifgt{#1}{18}% \ST@fact@outofrange @@ -1321,7 +1291,7 @@ } \newif\ifST@gcd -\newcommand\ST@arithmetic[2]{% #1 est une liste de nombres s\'epar\'es par des virgules, #2 la sc qui reçoit leur pgcd ou ppcm selon \ifST@gcd +\def\ST@arithmetic#1#2{% #1 est une liste de nombres s\'epar\'es par des virgules, #2 la sc qui reçoit leur pgcd ou ppcm selon \ifST@gcd \ST@split{#1},#2\ST@argB \ST@Ifinstr\ST@argB,{\ST@split\ST@argB,\ST@argB\ST@remain\let\ST@next\ST@arithmetic}{\let\ST@remain\@empty\let\ST@next\@gobbletwo}% \let\ST@argA#2% @@ -1342,45 +1312,45 @@ \expandafter\expandafter\expandafter\ST@next\expandafter\expandafter\expandafter{\expandafter#2\expandafter,\ST@remain}#2% } -\newcommand\ST@func@gcd[2]{% #1 est une liste de nombres s\'epar\'es par des virgules, #2 la sc qui reçoit leur pgcd +\def\ST@func@gcd#1#2{% #1 est une liste de nombres s\'epar\'es par des virgules, #2 la sc qui reçoit leur pgcd \ST@gcdtrue\ST@arithmetic{#1}#2% } -\newcommand\ST@func@lcm[2]{% #1 est une liste de nombres s\'epar\'es par des virgules, #2 la sc qui reçoit leur ppcm +\def\ST@func@lcm#1#2{% #1 est une liste de nombres s\'epar\'es par des virgules, #2 la sc qui reçoit leur ppcm \ST@gcdfalse\ST@arithmetic{#1}#2% } % d\'etermine la graine pour fp en fonction de la date et de l'heure -\newcommand\ST@seed{\FPseed\number\time\number\day\number\month} +\def\ST@seed{\FPseed\number\time\number\day\number\month} % la fonction randint -\newcommand\ST@func@randint[2]{% #1=sc contenant l'argument #2: sc recevant le r\'esultat +\def\ST@func@randint#1#2{% #1=sc contenant l'argument #2: sc recevant le r\'esultat \ST@Ifinstr#1,% s'il y a 2 nombres -> intervalle [nb1;nb2] {\ST@split#1,\ST@limita\ST@limitb - \FPifeq\ST@limita\ST@limitb\PackageError\ST@package@name{Macro function randint require two different numbers}\ST@seedoc@i\fi + \FPifeq\ST@limita\ST@limitb\PackageError\STname{Macro function randint require two different numbers}\ST@seedoc@i\fi \FPifgt\ST@limita\ST@limitb \let\ST@temp@a\ST@limitb\let\ST@limitb\ST@limita\let\ST@limita\ST@temp@a \fi - \FPifint\ST@limita\else\PackageError\ST@package@name{Macro function randint require integer argument}\ST@seedoc@i\fi - \FPifint\ST@limitb\else\PackageError\ST@package@name{Macro function randint require integer argument}\ST@seedoc@i\fi + \FPifint\ST@limita\else\ST@intarg@required\fi + \FPifint\ST@limitb\else\ST@intarg@required\fi \FPrandom#2% \FPeval#2{trunc(trunc(#2*(\ST@limitb-\ST@limita+1),0)+\ST@limita,0)}% }% - {\FPifint#1\else\PackageError\ST@package@name{Macro function randint require integer argument}\ST@seedoc@i\fi + {\FPifint#1\else\ST@intarg@required\fi \FPrandom#2% s'il n'y a qu'un nombre -> intervalle [0;nb2] \FPeval#2{trunc(#2*(#1+1),0)}% }% } -\newcommand\ST@func@rand[2]{% #1=sc contenant l'argument (ignor\'e) #2: sc recevant le r\'esultat - \FPrandom#2% -} +\def\ST@func@rand#1#2{\FPrandom#2}% #1=sc contenant l'argument (ignor\'e) #2: sc recevant le r\'esultat + +\def\ST@genzeros#1{\if#1m0\expandafter\ST@genzeros\fi} -\newcommand\ST@genzeros[1]{\if#1m0\expandafter\ST@genzeros\fi} -\newcommand\ST@powerten[2]{% g\'en\`ere 10^abs(#1) dans la sc #2 +\def\ST@powerten#1#2{% g\'en\`ere 10^abs(#1) dans la sc #2 \edef#2{1\expandafter\ST@genzeros\romannumeral\number\ifnum#1<\z@-\fi#1000\relax}% } -\newcommand\ST@func@scitodec[2]{% #1=sc contenant l'argument #2: sc recevant le r\'esultat + +\def\ST@func@scitodec#1#2{% #1=sc contenant l'argument #2: sc recevant le r\'esultat \expandafter\lowercase\expandafter{\expandafter\def\expandafter#1\expandafter{#1}}% \ST@Ifinstr#1{ee}% on regarde s'il y a "ee" {\ST@split#1{ee}\ST@mantissa\ST@exposant @@ -1388,16 +1358,16 @@ \csname FP\ifnum\ST@exposant<\z@ div\else mul\fi\endcsname#2\ST@mantissa\ST@tenpow}% {\IfDecimal#1% {\let#2#1}% - {\PackageError\ST@package@name{Illegal number in scitodec argument}\ST@seedoc@i}}% + {\PackageError\STname{Illegal number in scitodec argument}\ST@seedoc@i}}% } % les fonctions de test -\def\ST@list@offour#1,#2,#3,#4\@nil{% +\def\ST@liST@offour#1,#2,#3,#4\@nil{% \def\ST@argA{#1}\def\ST@argB{#2}\def\ST@argC{#3}\def\ST@argD{#4}% } -\newcommand\ST@def@funcif[3]{% - \expandafter\ST@list@offour#1\@nil +\def\ST@def@funcif#1#2#3{% + \expandafter\ST@liST@offour#1\@nil \FPeval\ST@argA\ST@argA\FPeval\ST@argB\ST@argB \csname FPif#3\endcsname\ST@argA\ST@argB \FPset#2\ST@argC @@ -1406,12 +1376,12 @@ \fi } -\newcommand\ST@func@ifeq[2]{\ST@def@funcif#1#2{eq}} -\newcommand\ST@func@ifgt[2]{\ST@def@funcif#1#2{gt}} -\newcommand\ST@func@iflt[2]{\ST@def@funcif#1#2{lt}} +\def\ST@func@ifeq#1#2{\ST@def@funcif#1#2{eq}} +\def\ST@func@ifgt#1#2{\ST@def@funcif#1#2{gt}} +\def\ST@func@iflt#1#2{\ST@def@funcif#1#2{lt}} % Transforme une date en nombre -\newcommand\ST@datetonum[4]{% #1=sc recevant le r\'esultat #2=jj #3=mm #4=aa +\def\STdatetonum#1#2#3#4{% #1=sc recevant le r\'esultat #2=jj #3=mm #4=aa \FPeval#1{#3+9-12*trunc((#3+9)/12,0)}% \FPeval\ST@@@year{#4-trunc(#1/10,0)}% \FPeval#1{365*\ST@@@year+trunc(\ST@@@year/4,0)-trunc(\ST@@@year/100,0)+trunc(\ST@@@year/400,0)+trunc((#1*306+5)/10,0)+#2-1}% @@ -1419,7 +1389,7 @@ } % Transforme un nombre en une date -\newcommand\ST@numtodate[4]{% #1=nombre repr\'esentant la date #2=jour #3=mois #4=ann\'ee +\def\ST@numtodate#1#2#3#4{% #1=nombre repr\'esentant la date #2=jour #3=mois #4=ann\'ee \FPeval#4{trunc((10000*#1+14780)/3652425,0)}% \FPeval#2{#1-(365*#4+trunc(#4/4,0)-trunc(#4/100,0)+trunc(#4/400,0))}% \FPifneg#2% @@ -1432,83 +1402,79 @@ \FPeval#3{#3+2-12*trunc((#3+2)/12,0)+1}\FPclip#3#3% } -\def\ST@parse@datefr#1/#2/#3\@nil{% - \def\ST@@@day{#1}\def\ST@@@month{#2}\def\ST@@@year{#3}% -} +\def\ST@parse@datefr#1/#2/#3\@nil{\def\ST@@@day{#1}\def\ST@@@month{#2}\def\ST@@@year{#3}} -\def\ST@parse@dateeng#1/#2/#3\@nil{% - \def\ST@@@day{#3}\def\ST@@@month{#2}\def\ST@@@year{#1}% -} +\def\ST@parse@dateeng#1/#2/#3\@nil{\def\ST@@@day{#3}\def\ST@@@month{#2}\def\ST@@@year{#1}} % transforme une date française courte du type jj/mm/aaaa en nombre -\newcommand\ST@func@frshortdatetonum[2]{% #1=sc \'etant l'argument jj/mm/aaaa #2=sc recevant le r\'esultat +\def\ST@func@frshortdatetonum#1#2{% #1=sc \'etant l'argument jj/mm/aaaa #2=sc recevant le r\'esultat \expandafter\ST@parse@datefr#1\@nil - \ST@datetonum#2\ST@@@day\ST@@@month\ST@@@year + \STdatetonum#2\ST@@@day\ST@@@month\ST@@@year } % Transforme un nombre en une date française de type jj/mm/aaaa -\newcommand\ST@func@numtofrshortdate[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtofrshortdate#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \ST@numtodate#1\ST@@@day\ST@@@month\ST@@@year \edef#2{\ST@@@day/\ST@@@month/\ST@@@year}% } % Transforme un nombre en une date longue française du type «14 juillet 1789» -\newcommand\ST@func@numtofrlongdate[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtofrlongdate#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \ST@numtodate#1\ST@@@day\ST@@@month\ST@@@year \edef#2{\ST@@@day\space\ifcase\ST@@@month\or janvier\or f\'evrier\or mars\or avril\or mai\or juin\or juillet\or ao\^ut\or septembre\or octobre \or novembre\or d\'ecembre\fi\space\ST@@@year}% } % Extrait d'un nombre repr\'esentant une date le mois en toutes lettres en français -\newcommand\ST@func@numtofrmonth[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtofrmonth#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \ST@numtodate#1\ST@@@day\ST@@@month\ST@@@year \edef#2{\ifcase\ST@@@month\or janvier\or f\'evrier\or mars\or avril\or mai\or juin\or juillet\or ao\^ut\or septembre\or octobre \or novembre\or d\'ecembre\fi}% } % Extrait d'un nombre rep\'esentant une date le nom du jour en français -\newcommand\ST@func@numtofrday[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtofrday#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \FPeval\ST@@@day{#1-7*trunc(#1/7,0)}\FPclip\ST@@@day\ST@@@day \edef#2{\ifcase\ST@@@day mercredi\or jeudi\or vendredi\or samedi\or dimanche\or lundi\or mardi\fi} } % transforme une date anglaise courte du type aaaa/mm/jj en nombre -\newcommand\ST@func@engshortdatetonum[2]{% #1=sc \'etant l'argument aaaa/mm/jj #2=sc recevant le r\'esultat +\def\ST@func@engshortdatetonum#1#2{% #1=sc \'etant l'argument aaaa/mm/jj #2=sc recevant le r\'esultat \expandafter\ST@parse@dateeng#1\@nil - \ST@datetonum#2\ST@@@day\ST@@@month\ST@@@year + \STdatetonum#2\ST@@@day\ST@@@month\ST@@@year } % Transforme un nombre en une date anglaise de type aaaa/mm/jj -\newcommand\ST@func@numtoengshortdate[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtoengshortdate#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \ST@numtodate#1\ST@@@day\ST@@@month\ST@@@year \edef#2{\ST@@@year/\ST@@@month/\ST@@@day} } % Transforme un nombre en une date longue anglaise du type «July 14, 1789» -\newcommand\ST@func@numtoenglongdate[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtoenglongdate#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \ST@numtodate#1\ST@@@day\ST@@@month\ST@@@year \edef#2{\ifcase\ST@@@month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi\space\ST@@@day,\space\ST@@@year}% } % Extrait d'un nombre repr\'esentant une date le mois en toutes lettres en anglais -\newcommand\ST@func@numtoengmonth[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtoengmonth#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \ST@numtodate#1\ST@@@day\ST@@@month\ST@@@year \edef#2{\ifcase\ST@@@month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi}% } % Extrait d'un nombre rep\'esentant une date le nom du jour en anglais -\newcommand\ST@func@numtoengday[2]{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat +\def\ST@func@numtoengday#1#2{% % #1=nombre repr\'esentant la date #2=sc recevant le r\'esultat \FPeval\ST@@@day{#1-7*trunc(#1/7,0)}\FPclip\ST@@@day\ST@@@day \edef#2{\ifcase\ST@@@day wednesday\or thursday\or friday\or saturday\or sunday\or monday\or tuesday\fi} } % Teste si la date contenue dans les 3 sc #1 (jour) #2(mois) #3(ann\'ee) est valide. Sinon, envoie un message d'erreur -\newcommand\ST@test@date@validity[3]{% - \IfInteger#1\relax\ST@invalid@date - \IfInteger#2\relax\ST@invalid@date - \IfInteger#3\relax\ST@invalid@date +\def\ST@teST@date@validity#1#2#3{% + \IfInteger#1{}\ST@invalid@date + \IfInteger#2{}\ST@invalid@date + \IfInteger#3{}\ST@invalid@date \ifnum#2<\@ne\ST@invalid@date\fi \ifnum#2>12 \ST@invalid@date\fi \ifnum#1<\@ne\ST@invalid@date\fi @@ -1517,13 +1483,13 @@ } % Transforme une date anglaise longue du type «July 14, 1789» en un nombre -\newcommand\ST@func@englongdatetonum[2]{% #1=sc contenant la date longue #2=sc recevant le r\'esultat +\def\ST@func@englongdatetonum#1#2{% #1=sc contenant la date longue #2=sc recevant le r\'esultat \ST@analyse@text@engdate#1\ST@@@day\ST@@@month\ST@@@year - \ST@datetonum#2\ST@@@day\ST@@@month\ST@@@year + \STdatetonum#2\ST@@@day\ST@@@month\ST@@@year } -\newcommand\ST@analyse@text@engdate[4]{% #1=texte repr\'esentant la date #2=jour #3=n° mois #4=ann\'ee - \ST@remove@first@spaces#1% +\def\ST@analyse@text@engdate#1#2#3#4{% #1=texte repr\'esentant la date #2=jour #3=n° mois #4=ann\'ee + \ST@remove@firST@spaces#1% \def\ST@today{\today}% \ifx#1\ST@today \edef#2{\number\day}\edef#3{\number\month}\edef#4{\number\year}% @@ -1547,28 +1513,28 @@ }[\def#3{-1}]% \ST@right#1\space#2% \ST@Ifinstr#2,{\ST@split#2,#2#4}{\ST@split#2{ }#2#4}% - \IfInteger#2\relax{\edef#2{\number\integerpart}}% + \IfInteger#2{}{\edef#2{\number\integerpart}}% \ST@removespaces#4% - \ST@test@date@validity#2#3#4% + \ST@teST@date@validity#2#3#4% \fi } % Transforme une date anglaise longue du type «14 juillet 1789» en un nombre -\newcommand\ST@func@frlongdatetonum[2]{% #1=sc contenant la date longue #2=sc recevant le r\'esultat +\def\ST@func@frlongdatetonum#1#2{% #1=sc contenant la date longue #2=sc recevant le r\'esultat \ST@analyse@text@frdate#1\ST@@@day\ST@@@month\ST@@@year - \ST@datetonum#2\ST@@@day\ST@@@month\ST@@@year + \STdatetonum#2\ST@@@day\ST@@@month\ST@@@year } \def\ST@utfencoding{utf8} -\newcommand\ST@analyse@text@frdate[4]{% #1=texte repr\'esentant la date #2=jour #3=n° mois #4=ann\'ee - \ST@remove@first@spaces#1% +\def\ST@analyse@text@frdate#1#2#3#4{% #1=texte repr\'esentant la date #2=jour #3=n° mois #4=ann\'ee + \ST@remove@firST@spaces#1% \def\ST@today{\today}% \ifx#1\ST@today \edef#2{\number\day}\edef#3{\number\month}\edef#4{\number\year}% \else \ST@split#1{ }#2#3% - \IfInteger#2\relax{\edef#2{\number\integerpart}}% + \IfInteger#2{}{\edef#2{\number\integerpart}}% \ST@split#3{ }#3#4% \ST@removespaces#3% \def\ST@e{^^e9}\def\ST@u{^^fb}% \'e et û en latin1 @@ -1583,15 +1549,16 @@ {avril}{\def#3{4}}{mai}{\def#3{5}}{juin}{\def#3{6}}% {juillet}{\def#3{7}}{aout}{\def#3{8}}{septembre}{\def#3{9}}% {octobre}{\def#3{10}}{novembre}{\def#3{11}}{decembre}{\def#3{12}}% - }[\def#3{-1}]% - \ST@test@date@validity#2#3#4% + } + [\def#3{-1}]% + \ST@teST@date@validity#2#3#4% \fi } -\newcommand\ST@func@tag[2]{% +\def\ST@func@tag#1#2{% \let#2\@empty \ifcsname ST@@\detokenize\expandafter{#1}\endcsname - \PackageWarning\ST@package@name{The tag "\detokenize\expandafter{#1}" already exists, previous is lost.}% + \PackageWarning\STname{The tag "\detokenize\expandafter{#1}" already exists, previous is lost.}% \fi \expandafter\edef\csname ST@@\detokenize\expandafter{#1}\endcsname{\number\ST@colcount,\number\ST@rowcount}% \ST@expadd@tomacro\ST@tag@list{% @@ -1599,17 +1566,17 @@ \expandafter\ST@coord@toref\csname ST@@\detokenize\expandafter{#1}\endcsname } -\newcommand\ST@func@cell[2]{% +\def\ST@func@cell#1#2{% \unless\ifcsname ST@@\detokenize\expandafter{#1}\endcsname\ST@unknown@tag\fi \edef#2{\csname ST@@\detokenize\expandafter{#1}\endcsname}% } -\newcommand\ST@func@row[2]{% +\def\ST@func@row#1#2{% \unless\ifcsname ST@@\detokenize\expandafter{#1}\endcsname\ST@unknown@tag\fi \edef#2{\expandafter\expandafter\expandafter\@gobble\csname ST@@\detokenize\expandafter{#1}\endcsname}% } -\newcommand\ST@func@col[2]{% +\def\ST@func@col#1#2{% \unless\ifcsname ST@@\detokenize\expandafter{#1}\endcsname\ST@unknown@tag\fi \edef#2{% \number\numexpr @@ -1617,7 +1584,15 @@ `\expandafter\expandafter\expandafter\@car\csname ST@@\detokenize\expandafter{#1}\endcsname\@nil-64}% } -% \newcommand\ST@func@timetosec[2]{% +\def\ST@func@value#1#2{% + \ifcsname ST@celltag@\detokenize\expandafter{#1}\endcsname + \expandafter\let\expandafter#2\csname ST@celltag@\detokenize\expandafter{#1}\endcsname + \else + \PackageWarning\ST@package@name{The tag "\detokenize\expandafter{#1}" does not exists, have you defined it?}% + \def#2{0}% use 0 if tag undefined + \fi +} +% \def\ST@func@timetosec#1#2{% % \ST@left{#1}:\ST@nb@hours % \ST@right{#1}:\ST@nb@min % \ST@Ifinstr\ST@nb@min:% @@ -1629,7 +1604,7 @@ % \FPclip#2#2% % } % -% \newcommand\ST@func@sectotime[2]{% +% \def\ST@func@sectotime#1#2{% % \FPeval\ST@nb@hours{trunc(#1/3600,0)}\FPclip\ST@nb@hours\ST@nb@hours % \FPeval\ST@nb@min{trunc((#1-\ST@nb@hours*3600)/60,0)}\FPclip\ST@nb@min\ST@nb@min % \FPeval\ST@nb@sec{#1-3600*\ST@nb@hours-60*\ST@nb@min}\FPclip\ST@nb@sec\ST@nb@sec @@ -1642,19 +1617,19 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%% Construction du tableau \'a afficher %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand\ST@search@lastshowcol{% cherche le num\'ero de la derni\`ere colonne non masqu\'ee +\def\ST@search@lastshowcol{% cherche le num\'ero de la derni\`ere colonne non masqu\'ee \ST@colcount\ST@total@colnumber% on commence par la fin \ST@search@lastshowcol@i } -\newcommand\ST@search@lastshowcol@i{% +\def\ST@search@lastshowcol@i{% \ST@Ifinstr{\ST@col@skiplist}{\expandafter(\number\ST@colcount)}% {\advance\ST@colcount\m@ne\ST@search@lastshowcol@i}% {\edef\ST@lastshowcol{\number\ST@colcount}}% } % cherche "<>" dans la sc #1 et remplace toutes ces occurences par le champ num\'erique de "ref" -\newcommand\ST@displaynumfields[1]{% +\def\ST@displaynumfields#1{% \StrBehind#1\ST@startdisplay[\ST@dipslaycell]% \StrBefore\ST@dipslaycell\ST@enddisplay[\ST@dipslaycell]% \let\ST@next\@gobble% \'a priori, on ne reboucle pas @@ -1668,18 +1643,19 @@ \unless\ifx\ST@decsep\ST@decsepfp\ST@substdecsep\ST@dipslaycell\fi% subsitution du s\'eparateur d\'ecimal s'il y a lieu \StrSubstitute#1\ST@next\ST@dipslaycell[#1]% on substitue <> par le champ num\'erique de la formule distante \let\ST@next\ST@displaynumfields - }\relax + } + {}% \fi \ST@next#1% } -\newcommand\ST@build@tab{% +\def\ST@build@tab{% \ST@rowcount\@ne\ST@colcount\@ne \expandafter\ST@expadd@tomacro\expandafter\ST@tab\csname endrow@0\endcsname% la (ou les) \'eventuelle ligne sup\'erieure du tableau \ST@build@tab@i } -\newcommand\ST@build@tab@i{% reconstitue le tableau \'a partir des valeurs calcul\'ees et des cellules +\def\ST@build@tab@i{% reconstitue le tableau \'a partir des valeurs calcul\'ees et des cellules \ifnum\ST@rowcount>\ST@total@rownumber \let\ST@nextcell\relax \else @@ -1704,7 +1680,8 @@ \ST@displaynumfields\ST@temp@a% affiche les champs num\'eriques des cellules entre << et >> \noexploregroups \ST@expadd@tomacro\ST@tab\ST@temp@a% on ajoute la cellule au tableau - }\relax + } + {}% }% \advance\ST@colcount\@ne% on passe \'a la colonne suivante ! \ST@ifvalid@csname{code@\number\ST@colcount @\number\ST@rowcount}% y a t-il encore un code d\'efini ensuite ? @@ -1714,7 +1691,7 @@ \advance\ST@colcount\m@ne \ST@ifvalid@csname{code@\number\ST@colcount @\number\ST@rowcount}% y a t-il un code d\'efini apr\`es le multicol ? {\ST@add@tomacro\ST@tab&}% on ajoute la tabulation - \relax + {}% \else% pas de \multicolumn \unless\ifST@hiddencol% si la cellule n'est pas masqu\'ee \unless\ifnum\ST@colcount>\ST@lastshowcol% si ce n'est pas la derni\`ere cellule affich\'ee @@ -1724,7 +1701,7 @@ \fi}% {\ST@ifvalid@csname{endrow@\number\ST@rowcount}% {\expandafter\ST@expadd@tomacro\expandafter\ST@tab\csname endrow@\number\ST@rowcount\endcsname}% ajoute la fin de la ligne - \relax + {}% \ST@colcount\@ne% on remet la colonne \'a 1 \advance\ST@rowcount\@ne% on passe \'a la ligne suivante }% @@ -1734,27 +1711,23 @@ } % format des lettres et nombres repr\'esentant les coordonn\'ees (helvetica gras tr\`es petit) -\newcommand\ST@debugformat@headers{% - \usefont{T1}{phv}{b}{n}% -} +\def\ST@debugformat@headers{\usefont{T1}{phv}{b}{n}} % format utilis\'e pour les cellules -\newcommand\ST@debug@format@cells{% - \usefont{T1}{lmtt}{m}{n}% -} +\def\ST@debug@format@cells{\usefont{T1}{lmtt}{m}{n}} -\newcommand\ST@colorcell{% - \ifST@colortblloaded\noexpand\cellcolor[gray]{.6}\fi -} +\def\ST@colorcell{\ifST@colortblloaded\noexpand\cellcolor[gray]{.6}\fi} -\newcommand\STdebug[1]{% +\def\STdebug#1{% \ST@debugmodetrue% on se met en mode d\'ebogage \begingroup \def\ST@debuginfo{#1}% \ifmmode\scriptscriptstyle\else\scriptsize\fi \def\ST@temp@a{formula}% pour n'afficher les fins de ligne que dans ce cas \IfStrEqCase\ST@debuginfo{% - {formula}\relax{text}\relax{code}\relax + {formula}{}% + {text}{}% + {code}{}% }[\ST@illegaldebugcommand]% \ST@debug@format@cells \tabcolsep0.3em @@ -1776,14 +1749,14 @@ \ifx\ST@temp@a\ST@debuginfo \ST@ifvalid@csname{endrow@\number\ST@rowcount}% {\detokenize\expandafter\expandafter\expandafter{\csname endrow@0\endcsname}}% - \relax + {}% \fi}% \noexpand\\\noexpand\cline{2-\number\numexpr\ST@lastshowcol+1}% }% \ST@debug@tab@i } -\newcommand\ST@debug@tab@i{% affiche le tableau de d\'ebobage +\def\ST@debug@tab@i{% affiche le tableau de d\'ebobage \ifnum\ST@rowcount>\ST@total@rownumber \ST@edefadd@tomacro\ST@debugtab{\noexpand\cline{2-\number\numexpr\ST@lastshowcol+1}\noexpand\end{tabular}}% \ST@debugtab% affichage du tableau de d\'ebogage @@ -1807,7 +1780,7 @@ \ifx\ST@temp@a\ST@debuginfo \ST@ifvalid@csname{endrow@\number\ST@rowcount}% {\detokenize\expandafter\expandafter\expandafter{\csname endrow@\number\ST@rowcount\endcsname}}% - \relax + {}% \fi}% \noexpand\\\noexpand\cline{2-\number\numexpr\ST@lastshowcol+1}}% \ST@colcount\@ne% on remet la colonne \'a 1 @@ -1825,32 +1798,30 @@ % d\'efinit quelle sera le s\'equence de conytr\^ole qui finira les lignes % dans les tableaux de spreadtab -\newcommand*\STeol[1]{\def\ST@eol{#1}} +\def\STeol#1{\def\ST@eol{#1}} \STeol\\ % renvoie la valeur num\'erique de la cellule de tag #1 -\newcommand\STtag[1]{% - \ifcsname ST@celltag@\detokenize\expandafter{#1}\endcsname\expandafter\@firstoftwo\else\expandafter\@scondoftwo\fi +\def\STtag#1{% + \ifcsname ST@celltag@\detokenize\expandafter{#1}\endcsname\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi {\csname ST@celltag@\detokenize\expandafter{#1}\endcsname} - {\PackageError\ST@package@name{Tag "#1" is unknown, have you defined it?}\ST@seedoc@i}% -} - -\newcommand*\STmakegtag[1]{% - \STmakegtag@i#1,\STmakegtag@i,% + {\PackageError\STname{Tag "#1" is unknown, have you defined it?}\ST@seedoc@i + }% } +\def\STmakegtag#1{\STmakegtag@i#1,\STmakegtag@i,} \def\STmakegtag@i#1,{% \ifx\STmakegtag@i#1% \else \def\ST@temp@a{#1}% \ifx\@empty\ST@temp@a - \PackageWarning\ST@package@name{An empty tag is ignored.}% + \PackageWarning\STname{An empty tag is ignored.}% \else \ifcsname ST@celltag@\detokenize\expandafter{#1}\endcsname \global\expandafter\let\csname ST@celltag@\detokenize\expandafter{#1}\expandafter\endcsname \csname ST@celltag@\detokenize\expandafter{#1}\endcsname \else - \PackageError\ST@package@name{Tag "#1" is unknown, have you defined it?}\ST@seedoc@i + \PackageError\STname{Tag "#1" is unknown, have you defined it?}\ST@seedoc@i \fi \fi \expandafter\STmakegtag@i @@ -1858,33 +1829,31 @@ } % d\'efinit le s\'eparateur d\'ecimal -\newcommand*\STsetdecimalsep[1]{\def\ST@decsep{#1}} +\def\STsetdecimalsep#1{\def\ST@decsep{#1}} \def\ST@decsepfp{.}% le s\'eparateur d\'ecimal donn\'e par fp \STsetdecimalsep.% le point par d\'efaut \STmessage{true}% affiche les messages par d\'efaut \newif\ifST@clipround -\newcommand*\STautoround{\@ifstar{\ST@cliproundfalse\ST@autoround}{\ST@cliproundtrue\ST@autoround}} -\newcommand*\ST@autoround[1]{\def\ST@rounddigit{#1}} +\def\STautoround{\@ifstar{\ST@cliproundfalse\ST@autoround}{\ST@cliproundtrue\ST@autoround}} +\def\ST@autoround#1{\def\ST@rounddigit{#1}} \STautoround{}% pas d'arrondi par d\'efaut -\newcommand\STsavecell[2]{% met dans la sc #1 la valeur du champ num\'erique de la cellule sp\'ecifi\'ee par sa r\'ef\'erence ABSOLUE +\def\STsavecell#1#2{% met dans la sc #1 la valeur du champ num\'erique de la cellule sp\'ecifi\'ee par sa r\'ef\'erence ABSOLUE \def\ST@temp@ref{#2}% - \ST@ifref\ST@temp@ref\relax\ST@illegal@ref - \ST@Ifinstr\ST@temp@ref[\ST@illegal@ref\relax + \ST@ifref\ST@temp@ref{}\ST@illegal@ref + \ST@Ifinstr\ST@temp@ref[\ST@illegal@ref{}% \expandafter\let\expandafter#1\csname formula@\ST@temp@formula\endcsname% le nombre est assign\'e \'a #1 \unless\ifx\ST@decsep\ST@decsepfp\ST@substdecsep#1\fi% et si le "." doit \^etre remplac\'e par "," on substitue \global\let#1#1% on rend l'assignation globale } -\long\def\ST@get@body@env#1\end{% - \expandafter\def\expandafter\ST@tab\expandafter{\ST@tab#1}\ST@find@end -} +\long\def\ST@get@body@env#1\end{\expandafter\def\expandafter\ST@tab\expandafter{\ST@tab#1}\ST@find@end} -\newcommand\ST@find@end[1]{% +\def\ST@find@end#1{% \def\ST@temp@a{#1}% - \ifx\ST@temp@a\ST@package@name + \ifx\ST@temp@a\STname \expandafter\spreadtab@i \else \ST@add@tomacro\ST@tab{\end{#1}}% @@ -1892,12 +1861,10 @@ \fi } -\long\def\ST@get@body@cs#1\endspreadtab{% - \def\ST@tab{#1}\spreadtab@i -} +\long\def\ST@get@body@cs#1\endspreadtab{\def\ST@tab{#1}\spreadtab@i} -\newcommand\spreadtab[2][]{% - \ifx\ST@package@name\@currenvir% on vient d'un \begin{spreadtab} ? +\newcommand*\spreadtab[2][]{% + \ifx\STname\@currenvir% on vient d'un \begin{spreadtab} ? \endgroup \let\ST@get@body\ST@get@body@env \else @@ -1915,15 +1882,15 @@ \let\ST@copylist\@empty \let\ST@row@skiplist\@empty \let\ST@col@skiplist\@empty - \def\ST@last@skipcol{0}% + \def\ST@laST@skipcol{0}% \edef\ST@previous@seed{\number\FPseed}% sauvegarde de la graine \ST@seed% graine variable - \ST@emit@message{New spreadtab: \string\begin\detokenize{#2}^^J* reading tab:}% + \ST@emit@message{^^JNew spreadtab: \string\begin\detokenize{#2}^^J* reading tab:}% \let\ST@tab\@empty \ST@get@body% met le code du tableau dans \ST@tab } -\newcommand\spreadtab@i{% +\def\spreadtab@i{% \let\ST@tag@list\@empty \let\ST@ref@found\@empty \ST@read@tab% analyse le tableau contenu dans \ST@tab @@ -1938,7 +1905,8 @@ \def\STdisplaytab{% \ST@debugmodefalse \ST@emit@message{\space\space\space\space\space Debug mode: display final tab^^J}% - \let\STdisplaytab\relax}% + \let\STdisplaytab\relax + }% \ST@optcode% ex\'ecute l'argument optionnel en ne tenant compte que de \STdisplaytab s'il y figure \unless\ifST@debugmode% si on doit afficher le tableau, on fait le boulot \ST@emit@message{* computing formulas:^^J}% @@ -1956,16 +1924,16 @@ \FPseed\ST@previous@seed% restauration de la graine \let\ifFPmessages\ST@FPmessages \restoreexpandmode\restoreexploremode - \ST@catocde@saved - \ST@tag@list + \ST@catocde@saved + \ST@tag@list \ST@sanitize@cs } -\newcommand\ST@sanitize@cs{% +\def\ST@sanitize@cs{% \ST@letname{endrow@0}\ST@undef@content \ST@sanitize@cs@i1} -\newcommand\ST@sanitize@cs@i[1]{% +\def\ST@sanitize@cs@i#1{% \unless\ifnum#1>\ST@total@rownumber \def\ST@temp@a{#1}% \ST@letname{endrow@#1}\ST@undef@content @@ -1974,7 +1942,7 @@ \fi } -\newcommand\ST@sanitize@cs@ii[1]{% +\def\ST@sanitize@cs@ii#1{% \unless\ifnum#1>\ST@total@colnumber \ST@letname{formula@#1@\ST@temp@a}\ST@undef@content \ST@letname{code@#1@\ST@temp@a}\ST@undef@content @@ -1984,7 +1952,6 @@ } \def\ST@undef@content{\ST@undef@content} - \endinput %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2143,5 +2110,13 @@ v0.4c 2014/11/06 \ST@analyse@text@engdate : si #1 commence par un espace parasite, celui-ci est d\'esormais retir\'e. 2 Bug corrig\'e dans \ST@displaynumfields : les macros - \ST@current@colnumber et \ST@current@rownumber sont définies avant - d'appeler \ST@ifref \ No newline at end of file + \ST@current@colnumber et \ST@current@rownumber sont d\'efinies avant + d'appeler \ST@ifref +------------------------------------------------------------------------------- +v0.4d 2018/01/02 + 1 Bug corrig\'e dans \ST@eval@cell : le \edef\ST@dependance@tree corrige + le \def ! + 2 Ajout d'un message d'erreur si une la fonction sum a une plage qui + contient la cellule courante elle-m\^eme + 3 Nouvelle macro fonction "value" + 4 Nettoyage du code \ No newline at end of file -- cgit v1.2.3