% % \iffalse % %% fancynum.dtx Copyright (C) J.J.Green 1999, 2000. %% $Id: fancynum.dtx,v 1.8 2000/08/08 22:28:38 jjg Exp $ %% %% This file is part of the fancynum package. %% %% It may be distributed under the terms of the LaTeX Project Public %% License, as described in lppl.txt in the base LaTeX distribution. %% Either version 1.0 or, at your option, any later version. %% %<*dtx> \ProvidesFile{fancynum.dtx} % %\NeedsTeXFormat{LaTeX2e}[1995/12/01] %\ProvidesPackage{fancynum} % \ProvidesFile{fancynum.sty} % \fi % \ProvidesFile{fancynum.dtx} [2000/08/08 0.92 Fancynum package] % % \iffalse %<*driver> \documentclass{ltxdoc} \newenvironment{option}[1]{\expandafter\macro\expandafter{% \csname ds@#1\endcsname}}{\endmacro} \begin{document} \DocInput{fancynum.dtx} \end{document} % % \fi % % \CheckSum{0} % % \GetFileInfo{fancynum.dtx} % % \title{The \textsf{fancynum} package\thanks{This file % has version number \fileversion, last % revised \filedate.}} % \author{J. J. Green} % \date{\filedate} % \maketitle% % % \changes{0.5}{2000/04/01}{Beta release} % % \def\star{{\ttfamily*}} % \makeatletter % \def\Describe@Macro#1{\endgroup % \setbox0=\lastbox\llap{\PrintDescribeMacro{#1}}}% % \makeatother % \marginparsep0pt % % \section{Introduction} % % The fancynum package is designed to aid the typesetting of numbers, % particularly (but not exclusively) the ASCII representation of % floating point numbers as written by computers. % % In the sequel we refer to the glyph used to separate the % integer and decimal parts of a decimal number as the % \emph{decimal symbol}, and that used to group the % digits of the integer and decimal parts as the % \emph{group symbol}. % % The author invites suggestions on improvements to the package. % In particular, any information on the typographic conventions % for setting numbers in different languages would be most % welcome. % % \section{Usage} % % The fancynum package is quite standard in its usage. After % including the package in the preamble, % the macro |\fnum| is available in mathematics mode. A call to % |$\fnum{3.141593e+05}$| will be set as $3{\cdot}141{,}593\times10^{5}$, % and so on. Further examples can be found in the file |examples.tex| % included in the distribution. % % The operation of the |\fnum| macro can be modified with % the commands |\setfnumdsym|, |\setfnumgsym| and |\setfnummsym|, % which set the value of the decimal, group and multiplication % symbols, respectively. % %\section{Limitations} % % The |\fnum| has some limitations on the form of its % argument: % \begin{itemize} % \item A decimal must have at least one digit either % side of the decimal symbol; % \item The optional exponential symbol must be |e|; % \item If the exponent must have at least one digit. % \end{itemize} % Consequently the strings |.312e20|, |312.e20| % and |3.142E20| are not acceptable arguments. % I hope to remove these restrictions at some point. % % \section{Package Options} % The package supports a small number of options. The % locale-specific options set default values for all of % the typographic parameters. The \textbf{english} option % uses the centred dot as the decimal symbol and a comma % as the group symbol. % The \textbf{french} option uses the comma as the decimal % symbol and a lower dot as the group symbol. Compare % the English $3{\cdot}141{,}593$ against the French $3{,}141.593$. % If no local-specific option is specified then English will % be taken as the default. % % The remaining options give specific values over the % typographic parameters, and override the locale-specific % options. % % The \textbf{tight} and \textbf{loose} options specify % space around the $\times$ in the setting of numbers in % exponential form. Compare the loose $2.3\times 10^{3}$ with % the tight $2.3{\times}10^{3}$. This option is useful where space % is at a premium, or may be preferred for {\ae}sthetic reasons. % % The \textbf{commas}, \textbf{thinspaces} and \textbf{plain} options % specify the group symbol to be used, respectively % |{,}|, |\,| and |\relax|. % % \section{Thanks} % I am grateful to Heiko Oberdiek, Norman Gray, Michael Downes % and Donald Arseneau for their assistance on |comp.text.tex|, % and to Jerzy Kucharczyk for providing a bug report. % % \section{Implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % \subsection{Typographic parameters} % % The decimal, group and multiplication symbols are stored in the % global variables |\fn@decimalsym| etc. % The following macros give access to the values used in the package. % \begin{macrocode} \def\setfnumdsym#1{\gdef\fn@decimalsym{#1}} \def\setfnumgsym#1{\gdef\fn@groupsym{#1}} \def\setfnummsym#1{\gdef\fn@multsym{#1}} % \end{macrocode} % % \subsection{Package options} % % The package options are simply calls the macro for the appropriate % parameter. % \begin{macrocode} \DeclareOption{english}{\setfnumdsym{{\cdot}}\setfnumgsym{{,}}} \DeclareOption{french}{\setfnumdsym{{,}}\setfnumgsym{{.}}} \DeclareOption{tight}{\setfnummsym{{\times}}} \DeclareOption{loose}{\setfnummsym{\times}} \DeclareOption{commas}{\setfnumgsym{{,}}} \DeclareOption{thinspaces}{\setfnumgsym{\,}} \DeclareOption{plain}{\setfnumgsym{\relax}} % \end{macrocode} % We set the default values before processing the options % \begin{macrocode} \ExecuteOptions{english,loose} \ProcessOptions\relax % \end{macrocode} % % \subsection{Utility macros} % % \begin{macro}{\fn@length} % Find the length of a string mod 3 (taken directly % from the example on p.~219 of the \TeX{}book). Here % though, a call to |\fn@length| assigns the calculated % value the (global) variable |\fn@strlen|. % \begin{macrocode} \newcount\fn@strlen \def\fn@length#1{\fn@strlen=0 \fn@getlength#1\end} \def\fn@getlength#1{\ifx #1\end \let\next=\relax \else \advance\fn@strlen by1 \ifnum\fn@strlen=3 \fn@strlen=0 \fi \let\next=\fn@getlength\fi \next} % \end{macrocode} % \end{macro} % % \subsection{Typesetting} % % \subsubsection{The decimal} % % \begin{macro}{\fn@fracpunct} % Punctuate the fractional part of a decimal. An % easy cyclic recursion. % \begin{macrocode} \def\fn@fracpunct#1{\fn@fpa#1@ } \def\fn@fpa#1#2#3 {#1\if #2@ \else \fn@fpb#2#3 \fi} \def\fn@fpb#1#2#3 {#1\if #2@ \else \fn@fpc#2#3 \fi} \def\fn@fpc#1#2#3 {#1\if #2@ \else \fn@groupsym\fn@fpa#2#3 \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\fn@intpunct} % Punctuate the integer part of a decimal. This is not as % easy as the fractional part since we need to know the length % before we start (no doubt there is a direct recursive method % to do this, but I'm not clever enough to work it out). % \begin{macrocode} \def\fn@intpunct#1{\fn@ipa#1 } % \end{macrocode} % The macro |\fn@ipa| prints the string's initial $\pm$ and passes % on the rest of the string to the |\fn@ipb| macro. It might be % worthwhile stripping the redundant `+' here, but I am minded not % to do this since whether it is present is the choice of the user % (unlike the redundancy in the sign of the exponent --- see below). % \begin{macrocode} \def\fn@ipa#1#2 {% \if +#1 +\fn@ipb#2 \else \if -#1 -\fn@ipb#2 \else \fn@ipb#1#2 \fi \fi} % \end{macrocode} % The |\fn@ipab| macro finds the length (modulo 3) with |\fn@strlen| % and calls the appropriate output macro. % \begin{macrocode} \def\fn@ipb#1 {\fn@length{#1} \ifcase\fn@strlen \fn@ipc#1 \or \fn@ipd#1 \or \fn@ipe#1 \fi} % \end{macrocode} % The |\fn@ip[cde]| macro prints the first couple of characters % and then calls |\fn@ipf| which calls |\fn@fpa| (see above) to % finish the job. % \begin{macrocode} \def\fn@ipc#1#2#3#4 {#1#2#3\fn@ipf#4@ } \def\fn@ipd#1#2 {#1\fn@ipf#2@ } \def\fn@ipe#1#2#3 {#1#2\fn@ipf#3@ } \def\fn@ipf#1#2 {\if #1@ \else \fn@groupsym\fn@fpa#1#2 \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\fn@decimal} % Set a proper decimal. % The pattern matching trick used here (and for the % exponent) is due to a conversation between % Heiko Oberdiek and Michael Downs on |comp.text.tex|. % See the file |ctt.txt| included in the distribution for details. % \begin{macrocode} \def\fn@propdecimal#1#2{\fn@intpunct{#1}\fn@decimalsym\fn@fracpunct{#2}} \def\fn@impropdecimal#1#2{\fn@intpunct{#1}} \def\fn@decimalsplit#1.#2.#3#4#5{#4{#1}{#2}} \def\fn@decimal#1{\fn@decimalsplit#1..\fn@propdecimal\fn@impropdecimal\empty} % \end{macrocode} % \end{macro} % % \subsubsection{The exponent} % % \begin{macro}{\fn@signedint} % Set a signed exponent. % The C standard I/O library functions \textit{printf}, % \textit{fprintf}, etc., as well as many Fortran compilers, % write a `+' in the exponent if it is positive. % Since this is superfluous, both typographically % and mathematically, we remove it if we find it. % \begin{macrocode} \def\fn@signedint#1#2 {% \if +#1 \fn@unsignedint#2\relax \else \if -#1 -\fn@unsignedint#2\relax \else \fn@unsignedint#1#2\relax \fi \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\fn@unsignedint} % Set an unsigned exponent. Here we remove leading zeros. % \begin{macrocode} \def\fn@unsignedint#1#2{% \ifx #2\relax \let\next=#1 \else \ifx 0#1 \let\next=\fn@unsignedint \else \let\next=#1 \fi \fi \next #2} % \end{macrocode} % \end{macro} % % \subsubsection{The general number} % % \begin{macro}{\fnum} % The setting of an floating point number. % Our processing is dependent on whether the argument contains % the letter `e'. % \begin{macrocode} \def\fn@exp#1#2{\fn@decimal{#1}\fn@multsym10^{\fn@signedint#2 }} \def\fn@noexp#1#2{\fn@decimal{#1}} \def\fn@realsplit#1e#2e#3#4#5{#4{#1}{#2}} \def\fnum#1{\fn@realsplit#1ee\fn@exp\fn@noexp\empty} % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \Finale