From 92a15e15b276458e10aa05016bf472e8c6dd3eb0 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Thu, 12 Jan 2006 23:45:13 +0000
Subject: context

git-svn-id: svn://tug.org/texlive/trunk@608 c570f23f-e606-0410-a88d-b1316a301751
---
 Master/texmf-dist/tex/context/base/core-con.tex | 987 ++++++++++++++++++++++++
 1 file changed, 987 insertions(+)
 create mode 100644 Master/texmf-dist/tex/context/base/core-con.tex

(limited to 'Master/texmf-dist/tex/context/base/core-con.tex')

diff --git a/Master/texmf-dist/tex/context/base/core-con.tex b/Master/texmf-dist/tex/context/base/core-con.tex
new file mode 100644
index 00000000000..a6d66641cc1
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/core-con.tex
@@ -0,0 +1,987 @@
+%D \module
+%D   [       file=core-con,
+%D        version=1997.26.08,
+%D          title=\CONTEXT\ Core Macros,
+%D       subtitle=Conversion Macros,
+%D         author=Hans Hagen,
+%D           date=\currentdate,
+%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{Context Core Macros / Conversion Macros}
+
+\unprotect
+
+%D This module deals with all kind of conversions from numbers
+%D and dates. I considered splitting this module in a support
+%D one and a core one, but to keep things simple as well as
+%D preserve the overview, I decided against splitting.
+
+%D \macros
+%D   {numbers}
+%D
+%D First we deal with the dummy conversion of numbers using the
+%D \TEX\ primitive \type{\number}. The uppercase alternative is
+%D only there for compatibility with the other conversion
+%D macros. We could do without \type{#1} but this way we get
+%D rid of unwanted braces. For the savety we also define a
+%D non||sence uppercase alternative.
+%D
+%D \showsetup{numbers}
+%D
+%D \starttyping
+%D \def\numbers#1{\number#1}
+%D \def\Numbers#1{\number#1}
+%D \stoptyping
+%D
+%D Due to read ahead, as in \type{[\pagenumber\space]} the space will
+%D disappear, unless we use:
+
+\def\numbers#1{\purenumber{#1}}
+\def\Numbers#1{\purenumber{#1}}
+
+
+%D \macros
+%D   {romannumerals,Romannumerals}
+%D
+%D \TEX\ the program uses a rather tricky conversion from
+%D numbers to their roman counterparts. This conversion could
+%D of course be programmed in \TEX\ itself, but I guess Knuth
+%D found the programming trick worth presenting.
+%D
+%D \showsetup{romannumerals}
+%D \showsetup{Romannumerals}
+%D
+%D When upcasing the result, we just follow the text book rules
+%D of expansion. Later on we'll see some more uppercase tricks.
+
+\def\romannumerals#1%
+  {\romannumeral#1}
+
+%D For some years we had \unknown
+%D
+%D \starttyping
+%D \def\Romannumerals#1%
+%D   {\uppercase\expandafter{\romannumeral#1}}
+%D \stoptyping
+%D
+%D \unknown but we need to be fully expandable in order to get
+%D the utility output file right, so now we have the following
+%D solution. It was Patrick Gundlach who first noticed this
+%D ommision.
+
+\def\Romannumerals#1%
+  {\expandafter\doRomannumerals\number#1\relax}
+
+\def\doRomannumerals#1#2\relax % spaces after ifcase prevent \relax
+  {\ifnum#1#2<10
+     \ifcase0#1#2 \or I\or II\or III\or IV\or V\or VI\or VII\or VIII\or IX\fi
+   \else\ifnum#1#2<100
+     \ifcase0#1   \or X\or XX\or XXX\or XL\or L\or LX\or LXX\or LXXX\or XC\fi
+     \doRomannumerals#2\relax
+   \else\ifnum#1#2<1000
+     \ifcase0#1   \or C\or CC\or CCC\or CD\or D\or DC\or DCC\or DCCC\or CM\fi
+     \doRomannumerals#2\relax
+   \else\ifnum#1#2<4000
+     \ifcase0#1   \or M\or MM\or MMM\fi
+     \doRomannumerals#2\relax
+   \else
+     \uppercase\expandafter{\romannumeral#1#2}%
+   \fi\fi\fi\fi}
+
+%D \macros
+%D   {character,Character}
+%D
+%D Converting a number into a character can of course only
+%D be done with numbers less or equal to~26. At the cost of
+%D much more macros a faster conversion is possible, using:
+%D
+%D \starttyping
+%D \setvalue{char1}{a} \def\character#1{\getvalue{char#1}}
+%D \stoptyping
+%D
+%D But we prefer a simpel \type{\case}.
+%D
+%D \showsetup{character}
+%D \showsetup{Character}
+
+\def\unknowncharacter{-} % else in lists \relax
+
+\def\character#1%
+  {\ifcase#1\unknowncharacter
+     \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%
+   \else
+     \unknowncharacter
+   \fi}
+
+\def\Character#1%
+  {\ifcase#1\unknowncharacter
+     \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%
+   \else
+     \unknowncharacter
+   \fi}
+
+%D \macros
+%D   {characters,Characters}
+%D
+%D Converting large numbers is supported by the next two
+%D macros. This time we just count on: $\cdots$~x, y, z, aa,
+%D ab, ac~$\cdots$.
+%D
+%D \showsetup{characters}
+%D \showsetup{Characters}
+
+\beginTEX
+
+\def\dodoconvertcharacters#1#2#3%
+  {\ifnum#3>#1
+     \bgroup
+     \!!counta#3\relax
+     \ifnum\!!counta>\zerocount
+       \advance\!!counta \minusone
+       \!!countb\!!counta
+       \divide\!!counta #1%
+       \!!countc\!!counta
+       \multiply\!!countc #1%
+       \advance\!!countb -\!!countc
+       \doconvertcharacters#3{\!!counta}%
+       \advance\!!countb \plusone
+       #3{\the\!!countb}%
+     \fi
+     \egroup
+   \else
+     #2{#3}% pure expansion, used in references
+   \fi}
+
+\endTEX
+
+%D A fully expandable alternative:
+
+\beginETEX \numexpr
+
+\def\dodoconvertcharacters#1#2#3%
+  {\ifcase#3\else
+     \ifnum#3>#1
+       \expandafter\doconvertcharacters\expandafter#2\expandafter{\the\numexpr(#3+12)/#1-1\relax}%
+       \expandafter#2\expandafter{\the\numexpr#3-((#3+12)/#1-1)*#1\relax}%
+     \else
+       \expandafter#2\expandafter{\number#3}%
+     \fi
+   \fi}
+
+\endETEX
+
+\def\doconvertcharacters{\dodoconvertcharacters{26}}
+
+\def\characters{\doconvertcharacters\character}
+\def\Characters{\doconvertcharacters\Character}
+
+%D \macros
+%D   {greeknumerals,Greeknumerals}
+%D
+%D Why should we only honour the romans, and not the greek?
+
+\def\greeknumerals#1%
+  {% no longer needed: \mathematics
+     {\ifcase#1\unknowncharacter\or
+        \alpha      \or \beta  \or \gamma   \or \delta   \or
+        \varepsilon \or \zeta  \or \eta     \or \theta   \or
+        \iota       \or \kappa \or \lambda  \or \mu      \or
+        \nu         \or \xi    \or \omicron \or \pi      \or
+        \varrho     \or \sigma \or \tau     \or \upsilon \or
+        \phi        \or \chi   \or \psi     \or \omega
+      \else
+        \unknowncharacter
+      \fi}}
+
+\def\Greeknumerals#1%
+  {% no longer needed: \mathematics
+     {\ifcase#1\unknowncharacter \or
+        \Alpha   \or \Beta  \or \Gamma   \or \Delta   \or
+        \Epsilon \or \Zeta  \or \Eta     \or \Theta   \or
+        \Iota    \or \Kappa \or \Lambda  \or \Mu      \or
+        \Nu      \or \Xi    \or \Omicron \or \Pi      \or
+        \Rho     \or \Sigma \or \Tau     \or \Upsilon \or
+        \Phi     \or \Xi    \or \Psi     \or \Omega
+      \else
+        \unknowncharacter
+      \fi}}
+
+%D \macros
+%D   {oldstylenumerals,oldstyleromannumerals}
+%D
+%D These conversions are dedicated to Frans Goddijn.
+
+\unexpanded\def\oldstylenumerals#1%
+  {{\os\number#1}}
+
+\unexpanded\def\oldstyleromannumerals#1%
+  {{\leftrulefalse\rightrulefalse\ss\txx\boxrulewidth.15ex
+    \ruledhbox spread .15em{\hss\uppercased{\romannumerals{#1}}\hss}}}
+
+%D \macros
+%D   {defineconversionvector,conversionnumber} % bad names so no danger for clash
+%D
+%D For Adam and friends \unknown
+%D
+%D \startitemize[persiannummerals]
+%D \item test \item test \item test \item test
+%D \stopitemize
+
+% \defineconversionvector{alpha}{`a}
+% \edef\test{\conversionnumber{alpha}{123}}
+
+% \ifx\gobbleoneargument\undefined \long\def\gobbleoneargument#1{} \fi
+
+\def\defineconversionvector#1#2% name base
+  {\bgroup
+   % dirty trick
+   \uccode`\*=`\1
+   % plain:
+   % \uccode`\0=\numexpr#2+0\relax \uccode`\1=\numexpr#2+1\relax
+   % \uccode`\2=\numexpr#2+2\relax \uccode`\3=\numexpr#2+3\relax
+   % \uccode`\4=\numexpr#2+4\relax \uccode`\5=\numexpr#2+5\relax
+   % \uccode`\6=\numexpr#2+6\relax \uccode`\7=\numexpr#2+7\relax
+   % \uccode`\8=\numexpr#2+8\relax \uccode`\9=\numexpr#2+9\relax
+   % context:
+   \dostepwiserecurse091{\expandafter\uccode\expandafter`\recurselevel=\numexpr#2+\recurselevel}%
+   % prepared macro
+   \uppercase\expandafter{\expandafter\gdef\csname::cvn::#1::\endcsname##*%
+     {\ifcase##* 0\or1\or2\or3\or4\or5\or6\or7\or8\or9\fi}}%
+   \egroup}
+
+\def\conversionnumber#1#2%
+  {\ifcsname::cvn::#1::\endcsname
+     \expandafter\doconversionnumber\csname::cvn::#1::\expandafter\endcsname\number#2\relax
+   \else
+      \number#2%
+   \fi}
+
+\def\doconversionnumber#1#2%
+  {\ifx#2\relax
+     \expandafter\gobbleoneargument
+   \else
+     #1{#2}%
+     \expandafter\doconversionnumber
+   \fi#1}
+
+%D \macros
+%D   {protectconversion}
+%D
+%D The previous two commands are not robust enough to be
+%D passed to \type{\write} en \type{\message}. That's why we
+%D introduce:
+
+\def\protectconversion
+  {\def\doconvertcharacters##1{##1}} % was \relax
+ %{\def\doconvertcharacters##1{\ifcase0##1 0\else##1\fi}} more save
+
+%D \macros
+%D   {normaltime,normalyear,normalmonth,normalday}
+%D
+%D The last part of this module is dedicated to converting
+%D dates. Because we want to use as meaningful commands as
+%D possible, and because \TEX\ already uses up some of those,
+%D we save the original meanings.
+
+\savenormalmeaning\time
+\savenormalmeaning\year
+\savenormalmeaning\month
+\savenormalmeaning\day
+
+%D \macros
+%D   {month,MONTH}
+%D
+%D Converting the month number into a month name is done
+%D using a case statement, abstact values and the label
+%D mechanism. This way users can easily redefine a label from
+%D for instance german into austrian.
+%D
+%D \starttyping
+%D \setuplabeltext [de] [january=J\"anner]
+%D \stoptyping
+%D
+%D Anyhow, the conversion looks like:
+
+\def\doconvertmonth#1%
+  {\labeltext
+     {\ifcase#1%
+      \or \v!january   \or \v!february \or \v!march    \or \v!april
+      \or \v!may       \or \v!june     \or \v!july     \or \v!august
+      \or \v!september \or \v!october  \or \v!november \or \v!december
+      \fi}}
+
+%D We redefine the \TEX\ primitive \type{\month} as:
+%D
+%D \showsetup{month}
+%D \showsetup{MONTH}
+
+\def\month
+  {\doconvertmonth}
+
+\def\MONTH#1%
+  {{\let\labeltext\LABELTEXT\month{#1}}}
+
+%D We never explicitly needed this, but Tobias Burnus pointed
+%D out that it would be handy to convert to the day of the
+%D week. In doing so, we have to calculate the total number of
+%D days, taking leapyears into account. For those who are
+%D curious:
+%D
+%D \startitemize[packed]
+%D \item  years that can be divided by 4 are leapyears
+%D \item  exept years that can be divided by 100
+%D \item  unless years can be divided by 400
+%D \stopitemize
+%D
+%D This makes the year 1900 into a normal year and 1996 and
+%D 2000 into leap years, right? Well, converting to string
+%D looks familiar:
+
+\def\doconvertday#1%
+  {\labeltext
+     {\ifcase#1
+      \or \v!sunday   \or \v!monday \or \v!tuesday  \or \v!wednesday
+      \or \v!thursday \or \v!friday \or \v!saturday \fi}}
+
+%D \macros
+%D   {getdayoftheweek, dayoftheweek}
+%D
+%D The conversion algoritm is an old one and a translation from
+%D a procedure written in MODULA~2 back in the 80's. I finaly
+%D found the 4--100-400 rules in some enclopedia. Look at this
+%D messy low level routine that takes the day, month and year
+%D as arguments:
+
+\newcount\normalweekday
+
+\def\getdayoftheweek#1#2#3%
+  {\bgroup
+   \!!counta#3\relax
+   \advance\!!counta \minusone
+   \!!countb\!!counta
+   \multiply\!!countb 365
+   \advance\!!countb \ifcase#2\relax
+     0 \or  0 \or 31 \or 59 \or 90 \or120 \or151 \or
+   181 \or212 \or243 \or273 \or304 \or334 \or365 \fi
+   \advance\!!countb #1\relax
+   \ifnum#2>2
+     \doifleapyearelse{#3}{\advance\!!countb 1}{}\relax
+   \fi
+   \!!countc\!!counta
+   \dosetdivision\!!countc4\!!countc
+   \advance\!!countb \!!countc
+   \!!countc\!!counta
+   \dosetdivision\!!countc{100}\!!countc
+   \advance\!!countb -\!!countc
+   \!!countc\!!counta
+   \dosetdivision\!!countc{400}\!!countc
+   \advance\!!countb \!!countc
+   \dosetmodulo\!!countb7\!!countb
+   \advance\!!countb \plusone
+   \@EA\egroup\@EA\normalweekday\the\!!countb\relax}
+
+\def\dayoftheweek#1#2#3%
+  {\getdayoftheweek{#1}{#2}{#3}\doconvertday{\normalweekday}}
+
+%D Using this macro in
+%D
+%D \startbuffer
+%D monday:   \dayoftheweek  {4} {5} {1992}
+%D friday:   \dayoftheweek {16} {6} {1995}
+%D monday:   \dayoftheweek {25} {8} {1997}
+%D saturday: \dayoftheweek {30} {8} {1997}
+%D tuesday:  \dayoftheweek  {2} {1} {1996}
+%D tuesday:  \dayoftheweek  {7} {1} {1997}
+%D tuesday:  \dayoftheweek {13} {1} {1998}
+%D friday:   \dayoftheweek  {1} {1} {2000}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D The macro \type {\getdayoftheweek} can be used to calculate
+%D the number \type {\normalweekday}.
+
+%D \macros
+%D   {weekday,WEEKDAY}
+%D
+%D The first one is sort of redundant. It takes the day
+%D number argument.
+%D
+%D \showsetup{weekday}
+%D \showsetup{WEEKDAY}
+
+\def\weekday
+  {\doconvertday}
+
+\def\WEEKDAY#1%
+  {{\let\labeltext\LABELTEXT\doconvertday{#1}}}
+
+%D \macros
+%D   {weekoftheday}
+%D
+%D {\em not yet implemented:}
+%D
+%D \starttyping
+%D \def\weekoftheday#1#2#3%
+%D  {}
+%D \stoptyping
+
+%D \macros
+%D   {doifleapyearelse,
+%D    getdayspermonth}
+%D
+%D Sometimes we need to know if we're dealing with a
+%D leapyear, so here is a testmacro:
+%D
+%D \starttyping
+%D \doifleapyearelse{year}{yes}{no}
+%D \stoptyping
+%D
+%D An example of its use can be seen in the macro
+%D
+%D \starttyping
+%D \getdayspermonth{year}{month}
+%D \stoptyping
+%D
+%D The number of days is available in the macro \type
+%D {\numberofdays}.
+
+\def\doifleapyearelse#1% #2#3%
+  {\bgroup
+   \!!doneafalse
+   \!!counta#1%
+   \dosetmodulo\!!counta4\!!countb
+   \ifcase\!!countb
+     \dosetmodulo\!!counta{100}\!!countb
+     \ifcase\!!countb \else \!!doneatrue \fi
+     \dosetmodulo\!!counta{400}\!!countb
+     \ifcase\!!countb \!!doneatrue \fi
+   \fi
+   \if!!donea
+     \egroup\@EA\firstoftwoarguments  % \def\next{#2}%
+   \else
+     \egroup\@EA\secondoftwoarguments % \def\next{#3}%
+   \fi}                               % \next}
+
+\def\getdayspermonth#1#2%
+  {\doifleapyearelse{#1}
+     {\def\numberofdays{29}}
+     {\def\numberofdays{28}}%
+   \edef\numberofdays
+     {\ifcase#2 \or31\or\numberofdays\or31\or30\or
+        31\or30\or31\or31\or30\or31\or30\or31\fi}}
+
+%D \macros
+%D   {currentdate, date}
+%D
+%D We use these conversion macros in the date formatting
+%D macro:
+%D
+%D \showsetup{currentdate}
+%D
+%D This macro takes care of proper spacing and delivers for
+%D instance:
+%D
+%D \startbuffer
+%D \currentdate[weekday,day,month,year] % still dutch example
+%D \currentdate[WEEKDAY,day,MONTH,year] % still dutch example
+%D \stopbuffer
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D depending of course on the keywords. Here we gave:
+%D
+%D \typebuffer
+%D
+%D If needed one can also add non||keywords, like in
+%D
+%D \startbuffer
+%D \currentdate[dd,--,mm,--,yy]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or typeset: \getbuffer.
+%D
+%D When no argument is passed, the current date is given as
+%D specified per language (using \type{\installlanguage}).
+%D
+%D \showsetup{currentdate}
+%D
+%D \startbuffer
+%D \date
+%D \date[d=12,m=12,y=1998][weekday]
+%D \date[d=12,m=12,y=1998]
+%D \stopbuffer
+%D
+%D We can also typeset arbitrary dates, using the previous
+%D command.
+%D
+%D \typebuffer
+%D
+%D The date is specified by one character keys. When no date
+%D is given, we get the current date.
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+\def\kenmerkdatumpatroon{j,mm,dd} % jj,mm,dd changed at januari 1-1-2000
+
+\newsignal\datesignal
+
+\def\dobetweendates
+  {\ifdim\lastskip=\datesignal\relax\else
+     \unskip\space
+     \hskip\datesignal\relax
+   \fi}
+
+% \def\complexcurrentdate[#1]%
+%   {\bgroup
+%    \let\labellanguage\currentlanguage
+%    \def\betweendates{\let\betweendates\dobetweendates}%
+%    \lowercase{\edef\!!stringa{#1}}% permits usage in \smallcapped
+%    \@EA\processallactionsinset\@EA
+%      [\!!stringa]
+%      [    \v!day=>\betweendates\the\normalday,
+%         %\v!day+=>\betweendates\ordinaldaynumber\normalday,
+%          \v!day+=>\betweendates\convertnumber{\v!day+}\normalday,
+%         \v!month=>\betweendates\month\normalmonth,
+%          \v!year=>\betweendates\the\normalyear,
+%         \v!space=>\unskip\ \hskip\datesignal,% optimization -)
+%               \ =>\unskip\ \hskip\datesignal,% optimization -)
+%                d=>\convertnumber\v!day\normalday,
+%              %d+=>\ordinaldaynumber\normalday,
+%               d+=>\convertnumber{\v!day+}\normalday,
+%                m=>\convertnumber\v!month\normalmonth,
+%                j=>\convertnumber\v!year\normalyear,
+%                y=>\convertnumber\v!year\normalyear,
+%                w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+%               dd=>\ifnum\normalday  >9 \else0\fi\the\normalday,
+%             %dd+=>\ordinaldaynumber{\ifnum\normalday >9 \else0\fi\the\normalday},
+%              dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday},
+%               mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth,
+%               jj=>\expandafter\gobbletwoarguments\the\normalyear,
+%               yy=>\expandafter\gobbletwoarguments\the\normalyear,
+%       \v!weekday=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+%      \v!referral=>\expanded{\complexcurrentdate[\kenmerkdatumpatroon]},
+%       \s!unknown=>\unskip
+%                   \commalistelement
+%                   \hskip\datesignal
+%                   \def\betweendates{\let\betweendates\dobetweendates}]%
+%    \ifdim\lastskip=\datesignal\relax
+%      \unskip
+%    \fi
+%    \egroup}
+
+\def\complexcurrentdate[#1]%
+  {\bgroup
+   \let\labellanguage\currentlanguage
+   \def\betweendates{\let\betweendates\dobetweendates}%
+   \processcommacommand[#1]\docomplexcurrentdate
+   \ifdim\lastskip=\datesignal\relax
+     \unskip
+   \fi
+   \egroup}
+
+\def\docomplexcurrentdate#1%
+  {\lowercase{\edef\!!stringa{#1}}% permits usage in \smallcapped
+   \processaction
+     [#1]
+     [    \v!day=>\betweendates\the\normalday,
+        %\v!day+=>\betweendates\ordinaldaynumber\normalday,
+         \v!day+=>\betweendates\convertnumber{\v!day+}\normalday,
+        \v!month=>\betweendates\month\normalmonth,
+         \v!year=>\betweendates\the\normalyear,
+        \v!space=>\unskip\ \hskip\datesignal,% optimization -)
+              \ =>\unskip\ \hskip\datesignal,% optimization -)
+               d=>\convertnumber\v!day\normalday,
+             %d+=>\ordinaldaynumber\normalday,
+              d+=>\convertnumber{\v!day+}\normalday,
+               m=>\convertnumber\v!month\normalmonth,
+               j=>\convertnumber\v!year\normalyear,
+               y=>\convertnumber\v!year\normalyear,
+               w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+              dd=>\ifnum\normalday  >9 \else0\fi\the\normalday,
+            %dd+=>\ordinaldaynumber{\ifnum\normalday >9 \else0\fi\the\normalday},
+             dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday},
+              mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth,
+              jj=>\expandafter\gobbletwoarguments\the\normalyear,
+              yy=>\expandafter\gobbletwoarguments\the\normalyear,
+      \v!weekday=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+     \v!referral=>\expanded{\complexcurrentdate[\kenmerkdatumpatroon]},
+      \s!unknown=>\unskip
+                  % #1 and not the lowercased \commalistelement, vietnamese has text
+                  % {} because #1 can have comma, like: {\ ,}
+                  {#1}%
+                  \hskip\datesignal
+                  \def\betweendates{\let\betweendates\dobetweendates}]}
+
+\def\simplecurrentdate
+  {\expanded{\complexcurrentdate[\currentdatespecification]}}
+
+\definecomplexorsimple\currentdate
+
+\def\dodate[#1][#2]%
+  {\bgroup
+   \iffirstargument
+     \getparameters[\??da][d=\normalday,m=\normalmonth,y=\normalyear,#1]%
+     \normalday  \@@dad\relax
+     \normalmonth\@@dam\relax
+     \normalyear \@@day\relax
+     \ifsecondargument
+       \currentdate[#2]%
+     \else
+       \currentdate
+     \fi
+   \else
+     \currentdate
+   \fi
+   \egroup}
+
+\def\date
+  {\dodoubleempty\dodate}
+
+%D \macros
+%D   {currenttime}
+%D
+%D The currenttime is actually the jobtime. You can specify
+%D a pattern similar to the previous date macro using the
+%D keys \type {h}, \type {m} and a separator.
+
+\def\calculatecurrenttime
+% {\DoDiv\time by60to\scratchcounter\edef\currenthour  {\the\scratchcounter}%
+%  \DoMod\time by60to\scratchcounter\edef\currentminute{\the\scratchcounter}}
+  {\dosetdivision\time{60}\scratchcounter
+   \edef\currenthour  {\ifnum\scratchcounter<10 0\fi \the\scratchcounter}%
+   \dosetmodulo  \time{60}\scratchcounter
+   \edef\currentminute{\ifnum\scratchcounter<10 0\fi \the\scratchcounter}}
+
+\appendtoks \calculatecurrenttime \to \everyjob
+
+\def\currenttimespecification{h,:,m}
+
+\def\complexcurrenttime[#1]%
+  {\calculatecurrenttime
+   \processallactionsinset[#1]
+     [h=>\currenthour,m=>\currentminute,\s!unknown=>\commalistelement]}
+
+\def\simplecurrenttime
+  {\expanded{\complexcurrenttime[\currenttimespecification]}}
+
+\definecomplexorsimple\currenttime
+
+%D Because we're dealing with dates, we also introduce a few
+%D day loops:
+%D
+%D \starttyping
+%D \processmonth{year}{month}{command}
+%D \processyear{year}{command}{before}{after}
+%D \stoptyping
+%D
+%D The counters \type {\normalyear}, \type {\normalmonth} and
+%D \type{\normalday} can be used for for date manipulations.
+
+\long\def\processmonth#1#2#3% year month command
+  {\bgroup
+   \getdayspermonth{#1}{#2}%
+   \dostepwiserecurse1\numberofdays1%
+     {\normalyear #1\relax
+      \normalmonth#2\relax
+      \normalday  \recurselevel\relax
+      #3}%
+   \egroup}
+
+\def\lastmonth{12} % can be set to e.g. 1 when testing
+
+\long\def\processyear#1#2#3#4% year command before after
+  {\bgroup
+   \dorecurse\lastmonth
+     {\normalyear #1\relax
+      \normalmonth\recurselevel\relax
+      #3\processmonth\normalyear\normalmonth{#2}#4}%
+   \egroup}
+
+%D \macros
+%D   {defineconversion, convertnumber}
+%D
+%D Conversion involves the macros that we implemented earlier
+%D in this module.
+%D
+%D \showsetup{defineconversion}
+%D \showsetup{convertnumber}
+%D
+%D We can feed this command with conversion macros as well as
+%D a set of conversion symbols. Both need a bit different
+%D treatment.
+%D
+%D \starttyping
+%D \defineconversion [roman] [\romannumerals]
+%D \defineconversion [set 1] [$\star$,$\bullet$,$\ast$]
+%D \stoptyping
+%D
+%D You can define a language dependent conversion with:
+%D
+%D \starttyping
+%D \defineconversion [en] [whatever] [\something]
+%D \stoptyping
+
+% \def\dodefineconversion[#1][#2]%
+%   {\ConvertConstantAfter\doifinstringelse{,}{#2}
+%      {\scratchcounter=0
+%       \def\docommando##1%
+%         {\advance\scratchcounter 1
+%          \setvalue{\??cv#1\the\scratchcounter}{##1}}%
+%       \processcommalist[#2]\docommando
+%       \setvalue{\??cv#1}##1{\csname\??cv#1##1\endcsname}}
+%      {\setvalue{\??cv#1}{#2}}}
+%
+% \def\defineconversion%
+%   {\dodoubleargument\dodefineconversion}
+
+\def\defineconversion
+  {\dotripleempty\dodefineconversion}
+
+\def\dodefineconversion[#1][#2][#3]%
+  {\ifthirdargument
+     \dododefineconversion[#1][#2][#3]%
+   \else
+     \dododefineconversion[][#1][#2]%
+   \fi}
+
+\def\dododefineconversion[#1][#2][#3]%
+  {\ConvertConstantAfter\doifinstringelse{,}{#3}
+     {\scratchcounter\zerocount
+      \def\docommando##1%
+        {\advance\scratchcounter \plusone
+         \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
+      \processcommalist[#3]\docommando
+      \setvalue{\??cv#1#2}##1{\csname\??cv#1#2##1\endcsname}}
+     {\setvalue{\??cv#1#2}{#3}}}
+
+% \def\convertnumber#1%
+%   {\csname\??cv#1\endcsname}
+
+% \def\convertnumber#1%
+%   {\csname\??cv
+%      \ifundefined{\??cv\currentlanguage#1}\else\currentlanguage\fi
+%    #1\endcsname}
+
+% \def\doifconversiondefinedelse#1%
+%   {\ifundefined{\??cv#1}%
+%      \@EA\secondoftwoarguments
+%    \else
+%      \@EA\firstoftwoarguments
+%    \fi}
+
+% \def\doifconversiondefinedelse#1%
+%   {\ifundefined{\??cv\ifundefined{\??cv\currentlanguage:#1}\else\currentlanguage\fi#1}%
+%      \@EA\secondoftwoarguments
+%    \else
+%      \@EA\firstoftwoarguments
+%    \fi}
+
+\beginETEX \ifcsname
+
+\def\convertnumber#1%
+  {\csname\??cv
+     \ifcsname\??cv\currentlanguage#1\endcsname
+       \currentlanguage#1%
+     \else\ifcsname\??cv#1\endcsname
+       #1%
+     \else
+       \s!default
+     \fi\fi
+   \endcsname}
+
+\def\doifconversiondefinedelse#1%
+  {\ifcsname\??cv\currentlanguage#1\endcsname
+     \@EA\firstoftwoarguments
+   \else\ifcsname\??cv#1\endcsname
+     \@EAEAEA\firstoftwoarguments
+   \else
+     \@EAEAEA\secondoftwoarguments
+   \fi\fi}
+
+\endETEX
+
+\beginTEX
+
+\def\convertnumber#1%
+  {\csname\??cv
+     \@EA\ifx\csname\??cv\currentlanguage#1\endcsname\relax
+       \@EA\ifx\csname\??cv#1\endcsname\relax
+         \s!default
+       \else
+         #1%
+       \fi
+     \else
+       \currentlanguage#1%
+     \fi
+   \endcsname}
+
+\def\doifconversiondefinedelse#1%
+  {\@EA\ifx\csname\??cv\currentlanguage#1\endcsname\relax
+     \@EA\ifx\csname\??cv#1\endcsname\relax
+       \@EAEAEA\secondoftwoarguments
+     \else
+       \@EAEAEA\firstoftwoarguments
+     \fi
+   \else
+     \@EA\firstoftwoarguments
+   \fi}
+
+\endTEX
+
+\defineconversion [\s!default] [\number]
+
+%D As longs as symbols are linked to levels or numbers, we can
+%D also use the conversion mechanism, but in for instance the
+%D itemization macros, we prefer symbols because they can more
+%D easier be (partially) redefined. Symbols are implemented
+%D in another module.
+
+\defineconversion []   [\numbers] % the default conversion
+
+\defineconversion [a]  [\characters]
+\defineconversion [A]  [\Characters]
+\defineconversion [AK] [\smallcapped\characters]
+\defineconversion [KA] [\smallcapped\characters]
+
+\defineconversion [n]  [\numbers]
+\defineconversion [N]  [\Numbers]
+\defineconversion [m]  [\mediaeval]
+
+\defineconversion [i]  [\romannumerals]
+\defineconversion [I]  [\Romannumerals]
+\defineconversion [r]  [\romannumerals]
+\defineconversion [R]  [\Romannumerals]
+\defineconversion [KR] [\smallcapped\romannumerals]
+\defineconversion [RK] [\smallcapped\romannumerals]
+
+\defineconversion [g]  [\greeknumerals]
+\defineconversion [G]  [\Greeknumerals]
+
+\defineconversion [o]  [\oldstylenumerals]
+\defineconversion [O]  [\oldstylenumerals]
+\defineconversion [or] [\oldstyleromannumerals]
+
+\defineconversion [\v!character]     [\character]
+\defineconversion [\v!Character]     [\Character]
+
+\defineconversion [\v!characters]    [\characters]
+\defineconversion [\v!Characters]    [\Characters]
+
+\defineconversion [\v!numbers]       [\numbers]
+\defineconversion [\v!Numbers]       [\Numbers]
+\defineconversion [\v!mediaeval]     [\mediaeval]
+
+\defineconversion [\v!romannumerals] [\romannumerals]
+\defineconversion [\v!Romannumerals] [\Romannumerals]
+
+\defineconversion [\v!greek]         [\greeknumerals]
+\defineconversion [\v!Greek]         [\Greeknumerals]
+
+\defineconversion [arabicnumerals]   [\numbers]
+\defineconversion [persiannumerals]  [\numbers]
+
+\beginXETEX \number
+
+\defineconversionvector{arabicnumerals}    {"0660}
+\defineconversionvector{persiannumerals}   {"06F0}
+\defineconversionvector{thainumerals}      {"0E50}
+\defineconversionvector{devanagarinumerals}{"0966}
+\defineconversionvector{gurmurkhinumerals} {"0A66}
+\defineconversionvector{gujaratinumerals}  {"0AE6}
+\defineconversionvector{tibetannumerals}   {"0F20}  % also "half numerals?"
+
+\defineconversion[arabicnumerals]    [\conversionnumber{arabicnumerals}]
+\defineconversion[persiannumerals]   [\conversionnumber{persiannumerals}]
+\defineconversion[thainumerals]      [\conversionnumber{thainumerals}]
+\defineconversion[devanagarinumerals][\conversionnumber{devanagarinumerals}]
+\defineconversion[gurmurkhinumerals] [\conversionnumber{gurmurkhinumerals}]
+\defineconversion[gujaratinumerals]  [\conversionnumber{gujaratinumerals}]
+\defineconversion[tibetannumerals]   [\conversionnumber{tibetannumerals}]
+
+\endXETEX
+
+% Some bonus ones:
+
+\defineconversion [\v!empty]         [\gobbleoneargument]
+\defineconversion [\v!none]          [\numbers]
+
+\defineconversion
+  [set 0]
+  [{\symbol[bullet]},
+   {\symbol[dash]},
+   {\symbol[star]},
+   {\symbol[triangle]},
+   {\symbol[circle]},
+   {\symbol[medcircle]},
+   {\symbol[bigcircle]},
+   {\symbol[square]}]
+
+\defineconversion
+  [set 1]
+  [\mathematics{\star},
+   \mathematics{\star\star},
+   \mathematics{\star\star\star},
+   \mathematics{\ddagger},
+   \mathematics{\ddagger\ddagger},
+   \mathematics{\ddagger\ddagger\ddagger},
+   \mathematics{\ast},
+   \mathematics{\ast\ast},
+   \mathematics{\ast\ast\ast}]
+
+\defineconversion
+  [set 2]
+  [\mathematics{*},
+   \mathematics{\dag},
+   \mathematics{\ddag},
+   \mathematics{**},
+   \mathematics{\dag\dag},
+   \mathematics{\ddag\ddag},
+   \mathematics{***},
+   \mathematics{\dag\dag\dag},
+   \mathematics{\ddag\ddag\ddag},
+   \mathematics{****},
+   \mathematics{\dag\dag\dag\dag},
+   \mathematics{\ddag\ddag\ddag\ddag}]
+
+\defineconversion
+  [set 3]
+  [\mathematics{\star},
+   \mathematics{\star\star},
+   \mathematics{\star\star\star},
+   \mathematics{\ddagger},
+   \mathematics{\ddagger\ddagger},
+   \mathematics{\ddagger\ddagger\ddagger},
+   \mathematics{\P},
+   \mathematics{\P\P},
+   \mathematics{\P\P\P},
+   \mathematics{\S},
+   \mathematics{\S\S},
+   \mathematics{\S\S\S},
+   \mathematics{\ast},
+   \mathematics{\ast\ast},
+   \mathematics{\ast\ast\ast}]
+
+\protect \endinput
-- 
cgit v1.2.3

