From a11217252edfb77b9feb9901511e71ec21c90665 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 29 Jun 2015 00:14:57 +0000 Subject: dozenal (28jun15) git-svn-id: svn://tug.org/texlive/trunk@37698 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/fonts/dozenal/dozenal.dtx | 423 ++++++++++++++++----- 1 file changed, 332 insertions(+), 91 deletions(-) (limited to 'Master/texmf-dist/source') diff --git a/Master/texmf-dist/source/fonts/dozenal/dozenal.dtx b/Master/texmf-dist/source/fonts/dozenal/dozenal.dtx index c357cc9b505..1a911b0d0e3 100644 --- a/Master/texmf-dist/source/fonts/dozenal/dozenal.dtx +++ b/Master/texmf-dist/source/fonts/dozenal/dozenal.dtx @@ -24,23 +24,37 @@ % \iffalse %\NeedsTeXFormat{LaTeX2e}[1999/12/01] -%\ProvidesPackage{dozenal}[2015/01/29 v5.3 support for dozenal fonts] +%\ProvidesPackage{dozenal}[2015/01/29 v6.0 support for dozenal fonts] %<*driver> \documentclass{ltxdoc} \usepackage{doc} +\usepackage{verbatim} \usepackage{url} \usepackage[typeone]{dozenal} \usepackage{mflogo} \usepackage{makeidx} \makeindex +\long\def\demonstrate#1#2{% + \bigskip% + \hrule% + \hbox to\linewidth{% + \hbox to0.5\linewidth{% + \vbox to2in{\vfil#1\vfil}% + }\hbox to0.5\linewidth{% + \vbox to2in{\vfil#2\vfil}% + }% + }% + \hrule% + \bigskip% +} \begin{document} \DocInput{dozenal.dtx} \end{document} % % \fi -% \title{The \texttt{dozenal} Package, v5.3} +% \title{The \texttt{dozenal} Package, v6.0} % \author{Donald P.\ Goodman III} % \date{\today} % @@ -113,10 +127,9 @@ % \item Provides default characters for the two transdecimal % digits, ``\x'' for ten and ``\e'' for eleven; these % correspond to the accepted Unicode standard digits -% ``turned digit two'' and ``turned digit three,'' which -% have been approved for inclusion in Unicode, and are -% expected to be part of the official standard sometime in -% 1200 (2016.). These characters copy-paste as ``X'' and +% ``turned digit two'' and ``turned digit three,'' which (as +% of June 11\e\e) are now part of the Unicode standard. +% These characters copy-paste as ``X'' and % ``E,'' the (somewhat) standard ASCII representations of % these two digits. However, other characters can easily be % substituted if desired. @@ -124,6 +137,8 @@ % classes (such as |article|, |book|, and so forth) to use % dozenal rather than decimal. This behavior can be shut % off if desired. +% \item Provides macros for converting dozenal numbers to +% words; e.g., ``3\e'' to ``three dozen eleven.'' % \end{itemize} % % That covered, we can now move on to how these features are @@ -172,12 +187,11 @@ % decimal from dozenal, if we wish. We do this with the % \DescribeMacro{\basex}|\basex| macro, which takes a single % argument, which is the dozenal number you wish to convert -% to decimal. This is subject to some pretty harsh -% restrictions, however. First, the only tokens allowed in -% the number are 0--9, |\x|, and |\e|. Second, these will -% only work with \emph{unexpanded} |\x| and |\e|. If you -% don't know what this means, then good for you; \TeX\ -% programmers will envy you. +% to decimal. This is subject to a pretty harsh +% restriction, however: the only tokens allowed in +% the number are 0--9, |X|, and |E|; putting in anything +% else will cause violent choking with ``expected a +% number''-type errors. % % To illustrate these limitations, let's define a new % counter and dozenize it. Here, we define the counter and @@ -197,35 +211,103 @@ % |\renewcommand\thetestcount{\basexii{\value{testcount}}{\x}{\e}}| % \end{quotation} % -% Now we get to do lovely things like the following: +% Now |dozenal| allow us to do lovely things like the following: % % \begin{quotation} % |\thetestcount| = \thetestcount % \end{quotation} % -% Now we can try to get that number in decimal with -% |\basex|. But don't try it; |\basex{\thetestcount}| -% doesn't work because the |\x| and |\e| are already -% expanded. Instead, use \LaTeX's built-in functions for -% chores like this: +% It's tempting to try to put that number into |\basex| to +% get it in decimal; but don't try it; +% |\basex{\thetestcount}| doesn't work because it contains +% expanded versions of |\x| and |\e|. Fortunately, you +% don't need it; \LaTeX\ already has the value of the +% |testcount| counter in its innards, and is quite used to +% outputting it in decimal: % % \begin{quotation} % |\arabic{testcount}| = \arabic{testcount} % \end{quotation} % % On the other hand, if you have an actual string you want -% converted, you can send it directly to |\basex| without -% worrying about expansion, because through much trial and -% error and banging head against wall, the expansion issues -% have already been resolved: +% converted, you can send it directly to |\basex|: % % \begin{quotation} -% |\basex{3\e}| = \basex{3\e} +% |\basex{3E}| = \basex{3E} % \end{quotation} % % So |\basex| is of limited utility, but it's a nice tool to % add to the box. % +% Finally, we can convert counters into \emph{words}, by +% supplying said counter's name to the +% \DescribeMacro{\doznumtoword}|\doznumtoword| macro. It +% takes as its argument the name of a \emph{counter} (not a +% number itself!) and converts this into words: +% +% \newcounter{somecount}\setcounter{somecount}{851} +% \begin{quote} +% |This page's number is ``\doznumtoword{page}.''| \\ +% This page's number is ``\doznumtoword{page}.'' +% \end{quote} +% +% This macro works with much larger numbers, as well. +% Purely for exemplary purposes, let's define a counter +% |somecount| with |\newcounter{somecount}|, and set it +% equal to (decimal) 851 with |\setcounter{somecount}{851}|. +% ``851'' +% in dozenal is ``5\x\e.'' Therefore, +% |\doznumtoword{somecount}| will yield +% ``\doznumtoword{somecount}.'' If you want to change the +% capitalization, use other macros; e.g., +% \DescribeMacro{\DOZnumtoword}|\DOZnumtoword{somecount}| gives +% ``\DOZnumtoword{somecount},'' while +% \DescribeMacro{\Doznumtoword}|\Doznumtoword{somecount| gives +% ``\Doznumtoword{somecount}.'' +% +% |\doznumtoword| (and friends) do act correctly when there +% are zeroes in the middle of the number, e.g., when +% |somecount| is equal to decimal 6977, which is dozenal +% 4055, it will output +% \setcounter{somecount}{6977}``\doznumtoword{somecount}.'' +% When there's a zero at the \emph{end} of the number, that +% zero is still output: |\doznumtoword{somecount}| where +% |somecount|\setcounter{somecount}{144} is equal to 144 gives +% ``\doznumtoword{somecount},'' not simply ``one biqua.'' I +% haven't decided yet if this is a bug or a feature; when I +% do, I'll act accordingly. +% +% The rank words (``unqua,'' ``biqua,'' and so forth) are +% all customizable by user-level commands, which are named +% |\dozrankoneword| for ``unqua,'' |\dozranktwoword| for +% ``biqua,'' and so forth. Simply redefine them like so: +% +% \begin{quote} +% |\def\dozrankoneword{dozen}|\def\dozrankoneword{dozen} \\ +% |\setcounter{somecount}{51}|\setcounter{somecount}{51} \\ +% |\doznumtoword{somecount}| = \doznumtoword{somecount} +% \end{quote} +% \def\dozrankoneword{unqua} +% +% This type of macro is useful for putting page numbers in +% both digits and words, for example. +% +% Lastly, |dozenal| allows the use of the common dozenal +% radix point, ``;'', to work properly in math mode. Some +% dozenalists prefer to use ``;'' rather than ``.'' (or +% ``,'') to mark the transition from integers to fractions +% in numbers; e.g., three-and-a-half is ``3;6.'' In math +% mode, however, this doesn't work; a semicolon in math +% mode is punctuation, and a spurious space is inserted +% (quite correctly) afterward. We don't want this space +% when we're using it as a radix point. So |dozenal| (using +% code adapted from Walter Schmidt's |icomma| package) fixes +% this: +% +% |$3;6$| = 3;6 +% +% And all is right with the world. +% % \section{Dozenal Characters and Fonts} % \label{sect:fonts} % @@ -309,6 +391,20 @@ % will yield ``\x'' or ``\e'' respectively. Other % characters will produce nothing. % +% As of v6.0, there are separate, hand-written versions of +% the tally marks, accessed by putting tallies in italic: +% +% \begin{center}\itshape +% \begin{tabular}{cccccc} +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% \Huge\tally{1} & \Huge\tally{2} & \Huge\tally{3} & \Huge\tally{4} & \Huge\tally{5} & \Huge\tally{6} \\ +% \end{tabular} +% \end{center} +% +% In other words, to get these shapes, say +% |\textit{\tally{6}}|; this will give you +% ``\textit{\tally{6}}.'' +% % The fonts are all prefixed |dozch|, if for some reason % direct access to them is needed. % @@ -338,7 +434,7 @@ % package (|\basexii|, |\dozens|, etc.) are made available, % but all the counters will still be in decimal. This % permits using dozenal characters in an otherwise decimal -% document; it also proves useful in dozenal document in +% document; it also proves useful in document classes in % which these counters are undefined (e.g., |minimal|). % % The |dozenal| fonts were designed in \MF, and they are @@ -355,16 +451,23 @@ % \section{Implementation} % \label{sect:code} % -% Make sure that we have fixltx2e loaded, so that the -% |\TextorMath| magic will work. +% Make sure that we have |fixltx2e| loaded, so that the +% |\TextorMath| magic will work. Also, as of v6.0, we also +% require |xstring| to use |\IfStrEq| in the number-to-word +% code. % \begin{macrocode} \RequirePackage{fixltx2e} +\RequirePackage{xstring} % \end{macrocode} % Now we ensure that |ifpdf| is loaded, so that we can test % for pdf or dvi modes. % \begin{macrocode} \RequirePackage{ifpdf} % \end{macrocode} +% We also require |mfirstuc|, because it's \emph{great}: +% \begin{macrocode} +\RequirePackage{mfirstuc} +% \end{macrocode} % Now we declare the option ``nocounters'', which prevents % |dozenal| from redefining all the counters. This prevents % errors in document classes which don't have these counters, @@ -433,8 +536,8 @@ \fi% \newcommand\x{\TextOrMath{\protect\doz{{X}}}{\doz@X}}% \newcommand\e{\TextOrMath{\protect\doz{{E}}}{\doz@E}}% -\DeclareMathSymbol{\doz@X}{\mathord}{dozens}{88} -\DeclareMathSymbol{\doz@E}{\mathord}{dozens}{69} +\DeclareMathSymbol{\doz@X}{\mathord}{dozens}{88}% +\DeclareMathSymbol{\doz@E}{\mathord}{dozens}{69}% % \end{macrocode} % Put in some additional code for the tally marks. % \begin{macrocode} @@ -459,73 +562,74 @@ % \end{macrocode} % Now that we can convert numbers \emph{to} dozenal, let's % set it up so that we can convert them \emph{from} dozenal. -% This is pretty ugly stuff here, because it's mostly -% straight \TeX\ (and e-\TeX) without higher-level -% conveniences, and because it's an expansion nightmare. If -% we didn't have to account for |\x| and |\e| because -% included in such strings, it's fairly easy; but it took a -% great deal of troubleshooting to make it work with them. -% -% First, we work up some macros to help us count the -% characters in an argument (the same, more or less, as is -% used in the |basicarith| package, adapted from those by -% ``Florent'' at \url{tex-and-stuff.blogspot.com}); then, we convert to -% decimal with |\basex|. +% I use |xstring| here, replacing a messy macro mesh from +% the last version (5.3). % \begin{macrocode} -\newcount\b@charcount -\def\gobblechar{\let\char= } -\def\assignthencheck{\afterassignment\checknil\gobblechar} -\def\countunlessnil{% - \ifx\char\nil \let\next=\relax% - \else% - \let\next=\auxcountchar% - \advance\b@charcount by1% - \fi% - \ifx\char\backslash\advance\b@charcount by-1\fi% - \next% +\newcount\doz@countchar +\def\doz@charcount#1{% + \StrLen{#1}[\doz@filler]% + \doz@countchar=\doz@filler% }% -\def\auxcountchar{% - \afterassignment\countunlessnil\gobblechar% +% \end{macrocode} +% Now we develop our conversion routines for |\basex|. For +% v6.0, these were hugely simplified by using the |xstring| +% package instead of trying to bash through in plain +% \TeX, which eventually worked but was \emph{not} pretty. +% We start by defining a few counters to help us out: +% \begin{macrocode} +\newcount\doz@lfiller\doz@lfiller=-1% +\newcount\doz@total\doz@total=0% +\newcount\doz@loopi\doz@loopi=0% +\newcount\doz@multiplier\doz@multiplier=1% +% \end{macrocode} +% Next we adopt a macro from TeX.SE question 140476, from +% user "Dan", which works like a charm even when using +% counter values rather than simple integers. These macros +% let us grab an individual character from a string; in this +% case, from the argument of |\basex|. +% \begin{macrocode} +% macro from TeX.SE question 140476, posted by user "Dan" +\def\ninthofmany#1#2#3#4#5#6#7#8#9{#9\gobbletorelax} +\def\gobbletorelax#1\relax{} +\def\doz@CharAt#1#2{% + \expandafter\ninthofmany\romannumeral\numexpr(9000-\number#1000)#2\relax} +% end "Dan" macro +% \end{macrocode} +% Here's where the money happens. We loop through each +% digit of the argument, multiplying it by the appropriate +% factor of 10 (the dozen, of course), and then add that to +% a rolling total. At the end, we output the number. +% \begin{macrocode} +\def\doz@ten{X}% +\def\doz@elv{E}% +\def\doz@basex#1{% + \doz@total=0% + \doz@loopi=\doz@countchar% + \doz@multiplier=1% + \def\doz@wholenum{#1}% + \loop\ifnum\doz@loopi>0% + \def\doz@currchar{\doz@CharAt{\number\doz@loopi}{\doz@wholenum}}% + \if\doz@currchar\doz@ten% + \doz@lfiller=10% + \else\if\doz@currchar\doz@elv% + \doz@lfiller=11% + \else% + \doz@lfiller=\doz@currchar% + \fi\fi% + \multiply\doz@lfiller by\doz@multiplier% + \multiply\doz@multiplier by12% + \advance\doz@total by\doz@lfiller% + \advance\doz@loopi by-1% + \repeat% + \the\doz@total% }% -\def\countchar#1{\def\xx{#1}\b@charcount=0\expandafter\auxcountchar\xx\nil} -%end Florent code -\def\gobble#1{}% -\newcount\@numdigs% -\newcount\@decmult% -\newcount\@loopindex\@loopindex=1% -\newcount\@decnum\@decnum=0% -\newcount\@digit\@digit=1% \def\basex#1{% - \countchar{#1}\@numdigs=\b@charcount% - \@decmult=1\@loopindex=1% - \loop\ifnum\@loopindex<\@numdigs% - \multiply\@decmult by12% - \advance\@loopindex by1% - \repeat% - \@loopindex=0% - \def\isten{x}\def\iselv{e}\def\isquote{\backslash}% - \edef\@doznum{\detokenize{#1}\relax}% - \@decnum=0% - \loop\ifnum\@loopindex<\@numdigs% - \def\@firstchar{\expandafter\@car\@doznum\@nil}% - \if\@firstchar\@backslashchar - \edef\@doznum{\@removefirstdig{\@doznum}}% - \else - \if\@firstchar\isten\def\@firstchar{10}\fi - \if\@firstchar\iselv\def\@firstchar{11}\fi - \advance\@loopindex by1% - \@digit=\@firstchar% - \edef\@doznum{\@removefirstdig{\@doznum}}% - \multiply\@digit by\@decmult% - \advance\@decnum by\@digit% - \divide\@decmult by12% - \fi - \repeat - \the\@decnum% -} -\def\@removefirstdig#1{% - \expandafter\expandafter\expandafter\gobble\expandafter\string#1% -} + \doz@charcount{#1}% + \doz@loopi=0% + \doz@basex{#1}% + \doz@multiplier=1% + \doz@total=0% +}% % \end{macrocode} % Now, of course, we simply redefine all the counters. This % covers only those counters included in the basic \LaTeX\ @@ -662,6 +766,143 @@ } }{} % end redefinition of counters block % \end{macrocode} +% Now we begin the number-to-word macros. First, we define +% the macros which allow the user to specify his own words +% for each rank: +% \begin{macrocode} +\def\dozrankoneword{unqua} +\def\dozranktwoword{biqua} +\def\dozrankthreeword{triqua} +\def\dozrankfourword{quadqua} +\def\dozrankfiveword{pentqua} +\def\dozranksixword{hexqua} +\def\dozranksevenword{septqua} +\def\dozrankeightword{octqua} +\def\dozranknineword{ennqua} +\def\dozranktenword{decqua} +\def\dozrankelvword{elvqua} +% \end{macrocode} +% Then we define some |\if|s to help us decide how we should +% capitalize the end result. +% \begin{macrocode} +\newif\ifDOZcaps\DOZcapsfalse +\newif\ifDozcaps\Dozcapsfalse +% \end{macrocode} +% Then, we give some utility macros: +% \begin{macrocode} +\def\doz@expandloop#1{\doz@xloop#1\relax} +\def\doz@xloop#1{% + \ifx\relax#1\else% + \doz@numword#1% + \expandafter\doz@xloop\fi% +} +\def\printdozrankword{} +\def\doz@rankword{% + \ifnum\doz@countchar=12 + \def\printdozrankword{\dozrankelvword}% + \fi + \ifnum\doz@countchar=11 + \def\printdozrankword{\dozranktenword}% + \fi + \ifnum\doz@countchar=10 + \def\printdozrankword{\dozranknineword}% + \fi + \ifnum\doz@countchar=9 + \def\printdozrankword{\dozrankeightword}% + \fi + \ifnum\doz@countchar=8 + \def\printdozrankword{\dozranksevenword}% + \fi + \ifnum\doz@countchar=7 + \def\printdozrankword{\dozranksixword}% + \fi + \ifnum\doz@countchar=6 + \def\printdozrankword{\dozrankfiveword}% + \fi + \ifnum\doz@countchar=5 + \def\printdozrankword{\dozrankfourword}% + \fi + \ifnum\doz@countchar=4 + \def\printdozrankword{\dozrankthreeword}% + \fi + \ifnum\doz@countchar=3 + \def\printdozrankword{\dozranktwoword}% + \fi + \ifnum\doz@countchar=2 + \def\printdozrankword{\dozrankoneword}% + \fi + \ifnum\doz@countchar=1 + \def\printdozrankword{\relax}% + \fi + \advance\doz@countchar by-1 + \ifDOZcaps + \edef\printdozrankword{\uppercase{\printdozrankword}}% + \fi + \ifDozcaps + \edef\printdozrankword{\capitalisewords{\printdozrankword}}% + \fi + \ifnum\doz@countchar>0 + \ \printdozrankword\ % + \else + \printdozrankword% + \fi +}% +\def\doz@numword#1{% + \IfStrEq{#1}{0}{\def\doz@numberword{zero}}{}% + \IfStrEq{#1}{1}{\def\doz@numberword{one}}{}% + \IfStrEq{#1}{2}{\def\doz@numberword{two}}{}% + \IfStrEq{#1}{3}{\def\doz@numberword{three}}{}% + \IfStrEq{#1}{4}{\def\doz@numberword{four}}{}% + \IfStrEq{#1}{5}{\def\doz@numberword{five}}{}% + \IfStrEq{#1}{6}{\def\doz@numberword{six}}{}% + \IfStrEq{#1}{7}{\def\doz@numberword{seven}}{}% + \IfStrEq{#1}{8}{\def\doz@numberword{eight}}{}% + \IfStrEq{#1}{9}{\def\doz@numberword{nine}}{}% + \IfStrEq{#1}{X}{\def\doz@numberword{ten}}{}% + \IfStrEq{#1}{E}{\def\doz@numberword{eleven}}{}% + \ifDOZcaps + \edef\doz@numberword{\uppercase{\doz@numberword}}% + \fi + \ifDozcaps + \edef\doz@numberword{\makefirstuc{\doz@numberword}}% + \fi + \doz@numberword% + \doz@rankword% +}% +\def\doznumtoword#1{% + \edef\thenumber{\basexii{\value{#1}}{X}{E}}% + \expandafter\doz@charcount\expandafter{\thenumber}% + \expandafter\doz@expandloop\expandafter{\thenumber}% + \doz@countchar=0% +}% +\def\DOZnumtoword#1{% + \DOZcapstrue% + \doznumtoword{#1}% + \DOZcapsfalse% +}% +\def\Doznumtoword#1{% + \Dozcapstrue% + \doznumtoword{#1}% + \Dozcapsfalse% +}% +% \end{macrocode} +% Our last job is to make sure the semicolon (Humphrey +% point) works correctly as a radix point in math mode. +% This code is adapted from the |icomma| package by Walter +% Schmidt. +% \begin{macrocode} +\AtBeginDocument{% + \mathchardef\humphrey\mathcode`\;% + \mathcode`\;="8000 % +} +{\catcode`;=\active + \gdef;{\futurelet\@let@token\sm@rtsemi} +} +\def\sm@rtsemi{% + \ifx\@let@token\@sptoken \else + \ifx\@let@token\space \else + \mathord\fi\fi \humphrey} +% \end{macrocode} % And that's the end. Thanks for reading, % folks; please email me with any suggestions or improvements. % \printindex -- cgit v1.2.3