summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/fancynum/fancynum.dtx
blob: a049dad5d242e7b2dd1173ddb559dbc6a08a9edf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
%
% \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}
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}[1995/12/01]
%<package>\ProvidesPackage{fancynum}
%<driver> \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}
%</driver>
% \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}
%</package>
%    \end{macrocode}
%
% \Finale