%D \module
%D   [       file=core-fnt,
%D        version=1995.10.10,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Font Support,
%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 / Font Support}

\unprotect

%D \macros
%D   {compound}
%D
%D We will overload the already active \type {|} so we have
%D to save its meaning in order to be able to use this handy
%D macro.
%D
%D \starttyping
%D so test\compound{}test can be used instead of test||test
%D \stoptyping

\bgroup \catcode`\|=\@@active \gdef\compound#1{|#1|} \egroup

%D Here we hook some code into the clean up mechanism needed
%D for verbatim data.

\appendtoks
  \disablecompoundcharacters
  \disablediscretionaries
\to \everycleanupfeatures

%D \macros
%D   {kap,KAP,Kap,Kaps,nokap,userealcaps,usepseudocaps}
%D
%D We already introduced \type{\cap} as way to capitalize
%D words. This command comes in several versions:
%D
%D \startbuffer
%D \cap {let's put on a \cap{cap}}
%D \cap {let's put on a \nocap{cap}}
%D \CAP {let's put on a \\{cap}}
%D \Cap {let's put on a \\{cap}}
%D \Caps{let's put on a cap}
%D \stopbuffer
%D
%D \typebuffer
%D
%D Note the use of \type{\nocap}, \type{\\} and the nested
%D \type{\cap}.
%D
%D \startvoorbeeld
%D \startlines
%D \getbuffer
%D \stoplines
%D \stopvoorbeeld
%D
%D These macros show te main reason why we introduced the
%D smaller \type{\tx} and \type{\txx}.
%D
%D \starttyping
%D \cap\romannumerals{1995}
%D \stoptyping
%D
%D This at first sight unusual capitilization is completely
%D legal.
%D
%D \showsetup{smallcapped}
%D \showsetup{notsmallcapped}
%D \showsetup{CAPPED}
%D \showsetup{SmallCapped}
%D \showsetup{SmallCaps}
%D
%D The difference between pseudo and real caps is demonstrated
%D below:
%D
%D \startbuffer
%D \usepseudocaps \cap{Hans Hagen}
%D \userealcaps   \cap{Hans Hagen}
%D \stopbuffer
%D
%D \typebuffer
%D
%D \getbuffer
%D
%D The \type {\bgroup} trickery below is needed because of
%D \type {\groupedcommand}.

\def\usepseudocaps
  {\def\cap@@uppercase{\the\everyuppercase\uppercased}%
   \def\cap@@lowercase{\the\everylowercase\lowercased}%
   \def\cap@@visualize{\tx}}

\def\userealcaps
  {\let\cap@@uppercase\relax
  %\let\cap@@lowercase\relax % Definitely not!
   \def\cap@@visualize{\sc}}

\usepseudocaps

\unexpanded\def\smallcapped % else conflict with math
  {\futurelet\next\dosmallcapped}

\def\disablepseudocaps
  {\let\smallcapped\donothing}

\def\dosmallcapped
  {\ifx\next\bgroup
     \expandafter\dodosmallcapped\expandafter\relax
   \else
     \expandafter\dodosmallcapped
   \fi}

\def\dodosmallcapped#1#2%
  {\ifmmode\hbox\fi
   \bgroup
   \cap@@visualize
   \cap@@uppercase{#1{#2}}%
   \egroup}

\unexpanded\def\notsmallcapped#1%
  {\cap@@lowercase{#1}}

\unexpanded\def\CAPPED#1%
  {{\def\\##1{\smallcapped{##1}}#1}}

\unexpanded\def\SmallCapped#1%
  {\CAPPED{\\#1}}

\unexpanded\def\SmallCaps
  {\let\processword\SmallCapped
   \processwords}

%D Sure:

\def\kap{\smallcapped} % for old times sake

%D Some precautions for a \PLAIN\ \TEX\ definition.

\unexpanded\def\normalcap{\dohandlemathtoken{cap}}
\unexpanded\def\normalCap{\dohandlemathtoken{Cap}}

\def\cap{\mathortext\normalcap\smallcapped}
\def\Cap{\mathortext\normalCap\SmallCapped}

\appendtoks
    \let\cap\firstofoneargument
    \let\Cap\firstofoneargument
\to \simplifiedcommands

%D \macros
%D   {setupcapitals}
%D
%D By default we use pseudo small caps in titles. This can be
%D set up with:
%D
%D \showsetup{setupcapitals}

\let\normalsmallcapped\smallcapped

\def\setupcapitals
  {\dosingleempty\dosetupcapitals}

\def\dosetupcapitals[#1]%
  {\getparameters[\??kk][#1]%
   \doifelse\@@kktitle\v!yes
     {\definealternativestyle[\v!capital][\normalsmallcapped][\normalsmallcapped]%
      \definealternativestyle[\v!smallcaps][\sc][\sc]%
      \unexpanded\def\smallcapped{\normalsmallcapped}}
     {\definealternativestyle[\v!capital][\normalsmallcapped][\uppercased]%
      \definealternativestyle[\v!smallcaps][\sc][\uppercased]%
      \unexpanded\def\smallcapped{\doconvertfont\v!capital}}%
   \doifelse\@@kksc\v!yes
     \userealcaps
     \usepseudocaps}

\ifx\uppercased\undefined \let\uppercased\uppercase \fi
\ifx\lowercased\undefined \let\lowercased\lowercase \fi

% pretty tricky stuff:
%
% \usemodule[abr-01] \TEX \METAPOST \PPCHTEX \LATEX
% \usemodule[abr-02] \TEX \METAPOST \PPCHTEX \LATEX

%def\uppercased#1{{\forceunexpanded\xdef\@@globalcrap{\uppercase{#1}}}\@@globalcrap}
%def\lowercased#1{{\forceunexpanded\xdef\@@globalcrap{\lowercase{#1}}}\@@globalcrap}

\def\uppercased#1{{\forceunexpanded\xdef\@@expanded{\uppercase{#1}}}\@@expanded}
\def\lowercased#1{{\forceunexpanded\xdef\@@expanded{\lowercase{#1}}}\@@expanded}

\setupcapitals
  [\c!title=\v!yes,
   \c!sc=\v!no]

%D \macros
%D   {Word, Words, WORD, WORDS, doprocesswords}
%D
%D This is probably not the right place to present the next set
%D of macros.
%D
%D \starttyping
%D \Word {far too many words}
%D \Words{far too many words}
%D \WORD {far too many words}
%D \WORDS{far too many words}
%D \stoptyping
%D
%D \typebuffer
%D
%D This calls result in:
%D
%D \startvoorbeeld
%D \startlines
%D \getbuffer
%D \stoplines
%D \stopvoorbeeld
%D
%D \showsetup{Word}
%D \showsetup{Words}
%D \showsetup{WORD}
%D \showsetup{WORDS}

\def\doWord#1%
  {\bgroup
   \the\everyuppercase
   \uppercase{#1}%
   \egroup}

\unexpanded\def\Word#1%
  {\doWord#1}

\def\doprocesswords#1 #2\od
  {\ConvertToConstant\doifnot{#1}{}
     {\processword{#1} %
      \doprocesswords#2 \od}}

\def\processwords#1%
  {\doprocesswords#1 \od\unskip}

\let\processword\relax

\unexpanded\def\Words
  {\let\processword\Word
   \processwords}

\unexpanded\def\WORD#1%
  {\bgroup
   \let\smallcapped\firstofoneargument
   \let\WORD\firstofoneargument
   \douppercase{#1}%
   \egroup}

\unexpanded\def\WORDS#1%
  {\WORD{#1}}

%D \macros
%D   {stretched}
%D
%D Stretching characters in a word is a sort of typographical
%D murder. Nevertheless we support this manipulation for use in
%D for instance titles.
%D
%D \starttyping
%D \hbox to 5cm{\stretched{murder}}
%D \stoptyping
%D
%D \typebuffer
%D
%D or
%D
%D \startvoorbeeld
%D \getbuffer
%D \stopvoorbeeld
%D
%D \showsetup{stretched}

\def\stretched#1%
  {\ifvmode\hbox to \hsize\else\ifinner\else\hbox\fi\fi
   \bgroup\processtokens\relax\hss\relax{\hss\hss}{#1}\egroup}

%D \startbuffer
%D \stretched{Unknown Box}
%D \hbox to .5\hsize{\stretched{A Horizontal Box}}
%D \vbox to 2cm{\stretched{A Vertical Box}}
%D \hbox to 3cm{\stretched{sp{\'e}c{\`\i}{\"a}l}}
%D \stopbuffer
%D
%D \getbuffer
%D
%D The first line of this macros takes care of boxing. Normally
%D one will use an \type{\hbox} specification. The last line
%D shows how special characters should be passed.
%D
%D \typebuffer

%D \macros
%D   {stretchednormalcase, stretcheduppercase, stretchedlowercase}
%D
%D A convenient alternative is:
%D
%D \starttyping
%D \stretcheduppercase{Is this what you like?}
%D \stoptyping
%D
%D \typebuffer
%D
%D this one uses fixed skips and kerns.
%D
%D \startvoorbeeld
%D \getbuffer
%D \stopvoorbeeld
%D
%D The default skip can be set with:

% \def\stretchedspacefactor{4}
% \def\stretchedspaceamount{.25em}
%
% \unexpanded\def\stretcheduppercase#1%
%   {\bgroup
%    \the\everyuppercase
%    \uppercase{\def\textstring{#1}}%
%    \ifdim\stretchedspaceamount>\zeropoint
%      \def\textkern%
%        {\kern\stretchedspaceamount}%
%      \def\textskip%
%        {\scratchdimen=\stretchedspaceamount
%         \hskip\stretchedspacefactor\scratchdimen}%
%      \@EA\processtokens\@EA\relax\@EA\textkern\@EA\relax\@EA
%        \textskip\@EA{\textstring}%
%    \else
%      \textstring
%    \fi
%    \egroup}

%D Given the following settings, the space is 1em by default:

\def\stretchedspacefactor{4}
\def\stretchedspaceamount{.25em}
\def\stretchedbreaktokens{.@/}

\unexpanded\def\stretchednormalcase
  {\stretchedsomecase\firstofoneargument}

\unexpanded\def\stretcheduppercase
  {\stretchedsomecase{\the\everyuppercase\uppercase}}

\unexpanded\def\stretchedlowercase
  {\stretchedsomecase{\the\everylowercase\lowercase}}

\def\stretchedsomecase#1#2%
  {\bgroup
   #1{\def\textstring{#2}}%
   \ifdim\stretchedspaceamount>\zeropoint
     \def\textkern##1%
       {% beware: ##1 may not be \box\somebox -)
        \determinemidwordbreak{##1}{\stretchedbreaktokens}%
        \kern\stretchedspaceamount##1\domidwordbreak}%
     \def\textskip
       {\scratchdimen\stretchedspaceamount
        \hskip\stretchedspacefactor\scratchdimen}%
     \@EA\processtokens\@EA\relax\@EA\textkern\@EA\relax\@EA
       \textskip\@EA{\textstring}%
   \else
     \textstring
   \fi
   \egroup}

%D An auxiliary macro, see for usage \type {\stretcheduppercase}.

\let\domidwordbreak\relax

\def\setmidwordbreaktoken#1%
  {\sfcode`#1=5000\relax}

\def\determinemidwordbreak#1#2%
  {\edef\midwordbreaktokens{#2}%
   \ifx\midwordbreaktokens\empty
     \global\let\domidwordbreak\relax
   \else
     \setbox\scratchbox\hbox
       {\expandafter\handletokens\midwordbreaktokens\with\setmidwordbreaktoken
        a\space \!!dimena\lastskip
        #1\space\!!dimenb\lastskip \relax % needed
        \ifdim\!!dimena=\!!dimenb
          \globallet\domidwordbreak\relax
        \else
          \globallet\domidwordbreak\allowbreak
        \fi}%
   \fi}

%D \macros
%D   {underbar,underbars,
%D    overbar,overbars,
%D    overstrike,overstrikes,
%D    setupunderbar}
%D
%D In the rare case that we need undelined words, for instance
%D because all font alternatives are already in use, one can
%D use \type{\underbar} and \type{\overstrike} and their plural
%D forms.
%D
%D \startbuffer
%D \underbars{drawing \underbar{bars} under words is a typewriter leftover}
%D \overstrikes{striking words makes them \overstrike{unreadable} but
%D sometimes even \overbar{top lines} come into view.}
%D \stopbuffer
%D
%D \typebuffer
%D
%D \startvoorbeeld
%D \startlines
%D \getbuffer
%D \stoplines
%D \stopvoorbeeld
%D
%D The next macros are derived from the \PLAIN\ \TEX\ one, but
%D also supports nesting. The \type{$} keeps us in horizontal
%D mode and at the same time applies grouping.
%D
%D \showsetup{underbar}
%D \showsetup{underbars}
%D \showsetup{overbar}
%D \showsetup{overbars}
%D \showsetup{overstrike}
%D \showsetup{overstrikes}
%D
%D Although underlining is ill advised, we permit some
%D alternatives, that can be set up by:
%D
%D \showsetup{setupunderbar}
%D
%D The alternatives show up as
%D   {\setupunderbar [alternativevariant=a]\underbar{alternative a}},
%D   {\setupunderbar [alternativevariant=b]\underbar{alternative b}},
%D   {\setupunderbar [alternativevariant=c]\underbar{alternative c}}
%D and
%D   {\setupunderbar [rulethickness=1pt]\underbar{1pt width}},
%D   {\setupunderbar [rulethickness=2pt]\underbar{2pt width}},
%D or whatever. Because \type{\overstrike} uses the same
%D method, the settings also apply to that macro.

\newcounter\underbarlevel

\def\underbarmethoda#1#2#3% RULE
  {\hbox to #1{\vrule\!!width#1\!!height#2\!!depth#3}}

\def\underbarmethodb#1#2#3% DASH
  {\hbox to #1
     {\hskip-.25em
      \xleaders
        \hbox{\hskip.25em\vrule\!!width.25em\!!height#2\!!depth#3}
        \hfil}}

\def\underbarmethodc#1#2#3% PERIOD
  {\hbox to #1
     {\dimen4=#3
      \advance\dimen4 .2ex
      \hskip-.25em
      \xleaders
        \hbox{\hskip.25em\lower\dimen4\hbox{.}}
        \hfil}}

\def\dododounderbar#1#2#3%
  {\startmathmode
   \setbox0\hbox{#3}%
   \setbox2\hbox{\color[\@@onrulecolor]{\getvalue{underbarmethod\@@onalternative}{\wd0}{#1}{#2}}}%
   \wd0\zeropoint
   \ht2\ht0
   \dp2\dp0
   \box0\box2
   \stopmathmode}

\unexpanded\def\dodounderbar#1%
  {\bgroup
   \dimen0=\@@onbottomoffset
   \dimen0=\underbarlevel\dimen0
   \ifdone \else
    %\advance\dimen0 -1pt
     \advance\dimen0 -\strutht
   \fi
   \dimen2\dimen0
   \advance\dimen2 \@@onrulethickness
   \dododounderbar{-\dimen0}{\dimen2}{#1}%
   \egroup}

\def\betweenunderbarwords
  {\bgroup
   \setbox0\hbox{\dodounderbar{\hskip\interwordspace}}%
   \nobreak
   \hskip\zeropoint\!!minus\interwordshrink
   \discretionary{}{}{\box0}%
   \egroup}

\def\betweenunderbarspaces
  {\hskip\currentspaceskip}

% \unexpanded\def\dounderbar#1#2%
%   {\let\betweenisolatedwords#1%
%    \processisolatedwords{#2}\dodounderbar
%    \egroup}

\unexpanded\def\underbar
  {\bgroup
   \increment\underbarlevel
   \donetrue
   \dounderbar\betweenunderbarwords}

\unexpanded\def\dounderbar#1%
  {\let\betweenisolatedwords#1%
   \dosingleempty\redounderbar}

\unexpanded\def\redounderbar[#1]#2%
  {\iffirstargument\setupunderbar[#1]\fi
   \processisolatedwords{#2}\dodounderbar
   \egroup}

\unexpanded\def\underbars
  {\bgroup
   \increment\underbarlevel
   \donetrue
   \dounderbar\betweenunderbarspaces}

\unexpanded\def\overbar
  {\bgroup
   \decrement\underbarlevel
   \donefalse
   \dounderbar\betweenunderbarwords}

\unexpanded\def\overbars
  {\bgroup
   \decrement\underbarlevel
   \donefalse
   \dounderbar\betweenunderbarspaces}

\def\dooverstrike#1%
  {\bgroup
   \dimen0=\@@ontopoffset
   \dimen2=\dimen0
   \advance\dimen2 \@@onrulethickness
   \dododounderbar{\dimen2}{-\dimen0}{#1}%
   \egroup}

\def\betweenoverstrikewords
  {\bgroup
   \setbox0\hbox{\dooverstrike{\hskip\interwordspace}}%
   \nobreak
   \hskip\zeropoint\!!minus\interwordshrink
   \discretionary{}{}{\box0}%
   \egroup}

\unexpanded\def\overstrike#1%
  {\bgroup
   \let\betweenisolatedwords\betweenoverstrikewords
   \processisolatedwords{#1}\dooverstrike
   \egroup}

\unexpanded\def\overstrikes#1%
  {\bgroup
   \processisolatedwords{#1}\dooverstrike
   \egroup}

\def\underbarparameter#1{\csname\??on#1\csname}

\def\setupunderbar
  {\dodoubleargument\getparameters[\??on]}

%D \macros
%D   {shiftedword, shiftedwords}
%D
%D Used as \type {\shiftedwords {10pt} {some text}} this macro will
%D move

% \def\shiftedword#1% #2%
%   {\raise#1\hbox} % {#2}} % officially: {\ifdim#1>\zeropoint\raise\else\lower\fi#1\hbox{#2}}

% \def\shiftedwords#1#2%
%   {\processisolatedwords{#2}{\shiftedword{#1}}}

%D \macros
%D   {low, high, lohi}
%D
%D Although \TEX\ is pretty well aware of super- and
%D subscripts, its mechanism is mainly tuned for math mode.
%D The next few commands take care of script texts both modes.
%D
%D \startbuffer
%D The higher\high{one goes} the lower\low{one drops}, or\lohi{yes}{no}?
%D \stopbuffer
%D
%D \typebuffer
%D
%D \getbuffer
%D
%D Note the different placement of \type {\lohi}, where we
%D need a bit more space. The implementation looks a bit
%D fuzzy, since some \type {\fontdimen}'s are involved to
%D determine the optimal placement.

\def\dodohighlow
  {\ifx\fontsize\empty
     \ifmmode
       \ifnum\fam<0 \tx \else \holamathfont \fi
     \else
       \tx
     \fi
   \else
     \tx
   \fi}

\def\dohighlow#1#2#3#4#5% todo, named fontdimens
  {\dontleavehmode
   \bgroup
   \scratchdimen\ifdim\fontexheight\textfont2=1ex #2\textfont2\else #3ex\fi
   \advance\scratchdimen #4ex
   \kern.1ex
   \setbox\scratchbox\hbox{#1\scratchdimen\hbox{\dodohighlow#5}}%
   \ht\scratchbox\strutheight
   \dp\scratchbox\strutdepth
   \box\scratchbox
   \egroup}

\unexpanded\def\high{\dohighlow\raise\mathsupnormal{.86}{0}}
\unexpanded\def\low {\dohighlow\lower\mathsubnormal{.48}{0}}

% \unexpanded\def\lohi#1#2%
%   {\dontleavehmode
%    \hbox
%      {\setbox4=\hbox{\dohighlow\lower\mathsubnormal{.48}{.1}{#1}}%
%       \setbox6=\hbox{\dohighlow\raise\mathsupnormal{.86}{.1}{#2}}%
%       \ifdim\wd4<\wd6
%         \wd4=\zeropoint\box4\box6
%       \else
%         \wd6=\zeropoint\box6\box4
%       \fi}}

\unexpanded\def\lohi
  {\dosingleempty\dolohi}

\def\dolohi[#1]#2#3%
  {\dontleavehmode
   \hbox
     {\setbox4\hbox{\dohighlow\lower\mathsubnormal{.48}{.1}{#2}}%
      \setbox6\hbox{\dohighlow\raise\mathsupnormal{.86}{.1}{#3}}%
      \doif{#1}{\v!left}
        {\ifdim\wd4<\wd6
          \setbox4\hbox to \wd6{\hss\box4}%
        \else
          \setbox6\hbox to \wd4{\hss\box6}%
        \fi}%
      \ifdim\wd4<\wd6
        \wd4=\zeropoint\box4\box6
      \else
        \wd6=\zeropoint\box6\box4
      \fi}}

%D You can provide an optional keyword \type {left}, in which
%D case the super and subscripts will be aligned in a way that
%D permits placement at the left of a word (which means that
%D it will be right aligned).
%D
%D \startbuffer
%D \lohi{aha}{ah} test \lohi{aha}{ah} test
%D \lohi[left]{aha}{ah} test \lohi[left]{aha}{ah} test
%D \lohi{aha}{ah} test\lohi{aha}{ah} test
%D \lohi[left]{aha}{ah}test \lohi[left]{aha}{ah}test
%D \stopbuffer
%D
%D \typebuffer
%D
%D \getbuffer

%D \macros
%D   {setupinitial,placeinitial,checkinitial}
%D
%D {\em To be documented.}
%D
%D \starttyping
%D \setupinitial[state=start] \placeinitial \input tufte
%D \stoptyping
%D
%D and
%D
%D \starttyping
%D \def\bpar{\ifvmode\checkinitial\fi}
%D \def\epar{\ifhmode\par\fi\checkinitial}
%D \stoptyping

%  to do: more fine tuning

\def\setupinitial
  {\dodoubleempty\getparameters[\??dc]}

\definefontsynonym[Initial][Regular] % prefered initial identifier
\definefontsynonym[initial][Initial] % internal but accepted too

\setupinitial
  [\c!state=\v!stop,
   \c!location=\v!text,
   \c!n=3,
   \c!distance=.125em,
   \c!command=,
   \s!font=initial]

\def\AutoDroppedCapsCommand{\NiceDroppedCaps\@@dccommand\@@dcfont\@@dcdistance\@@dcn}%

\def\placeinitial
  {\doifelse\@@dclocation\v!margin{\chardef\DropMode\plusone}{\chardef\DropMode\zerocount}%
   \doif    \@@dcstate\v!start{\ifcase\@@dcn\else\AutoDroppedCaps\fi}}

\let\checkinitial\CheckDroppedCaps

%D This module has only a few setups:

\setupunderbar
  [\c!alternative=a,
   \c!rulethickness=\linewidth,
   \c!bottomoffset=1.5pt,
   \c!topoffset=2.5pt,
   \c!rulecolor=]

\protect \endinput
