%D \module
%D   [       file=supp-fun,
%D        version=1995.10.10,
%D          title=\CONTEXT\ Support Macros,
%D       subtitle=Fun Stuff,
%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. 

\unprotect

%D This module implements some typographics tricks that can 
%D be fun when designing document layouts. The examples use
%D macros that are typical to \CONTEXT, but non \CONTEXT\
%D users can use the drop caps and first line treatment 
%D macros without problems. This module will be extended
%D when the need for more of such tricks arises.

\ifx \undefined \writestatus \input supp-mis.tex \relax \fi

\writestatus{loading}{Context Support Macros / Fun Stuff}

\ifx\definefont\undefined
  \def\definefont[#1][#2]{\expandafter\font\csname#1\endcsname=#2\relax}
\fi

%D \macros
%D   {DroppedCaps}
%D     
%D \startbuffer
%D \DroppedCaps 
%D   {\color[green]} {cmbx12} 
%D   {2.2\baselineskip} {2pt} {\baselineskip} {2} 
%D   Let's start
%D \stopbuffer
%D
%D \haalbuffer with dropped caps, those blown up first
%D characters of a paragraph. It's hard to implement a general
%D mechanism that suits all situations, but dropped caps are so 
%D seldomly used that we can permit ourselves a rather user
%D unfriendly implementation.
%D
%D \typebuffer
%D
%D As we will see, there are 7 different settings involved. The
%D first argument takes a command that is used to do whatever
%D fancy things we want to do, but normally this one will be
%D empty. The second argument takes the font. Because we're
%D dealing with something very typographic, there is no real
%D reason to adopt complicated font switching schemes, a mere
%D name will do. Font encodings can bring no harm, because the
%D alphanumeric characters are nearly always located at their
%D natural position in the encoding vector.
%D
%D \startbuffer
%D \DroppedCaps 
%D   {\color[red]} {cmbx12} 
%D   {\baselineskip} {0pt} {0pt} {1} 
%D   This simple
%D \stopbuffer
%D
%D \haalbuffer case shows us what happens when we apply minimal
%D values. Here we used:
%D
%D \typebuffer
%D
%D \startbuffer
%D \DroppedCaps 
%D   {\color[red]} {cmbx12} 
%D   {2\baselineskip} {0pt} {\baselineskip} {2} 
%D   In this ugly 
%D \stopbuffer
%D 
%D \haalbuffer example the third argument tells 
%D this macro that we want a dropped capital scaled to the 
%D baseline distance. The two zero point arguments are the 
%D horizontal and vertical offsets and the last arguments
%D determines the hanging indentation. In this paragraph we 
%D set the height to two times the baselinedistance and use 
%D two hanging lines: 
%D 
%D \typebuffer
%D 
%D Here, the first character is moved down one baseline. Here
%D we also see why the horizontal offset is important. The
%D first example (showing the~L) sets this to a few points and
%D also used a slightly larger height. 
%D
%D Of course common users (typist) are not supposed to see this
%D kind of fuzzy definitions, but fortunately \TEX\ permits us
%D to hide them in macros. Using a macro also enables us to
%D garantee consistency throughout the document:
%D
%D \startbuffer
%D \def\MyDroppedCaps%
%D   {\DroppedCaps 
%D      {\color[green]} {cmbx12} 
%D      {5\baselineskip} {3pt} {3\baselineskip} {4}}
%D
%D \MyDroppedCaps The implementation
%D \stopbuffer
%D 
%D \typebuffer
%D 
%D \haalbuffer of the general macro is rather simple and only
%D depends on the arguments given and the dimensions of the
%D strut box. We explicitly load the font, which is no problem
%D because \TEX\ does not load a font twice. We could have
%D combined some arguments, like the height, vertical offset
%D and the number of lines, but the current implementation
%D proved to be the most flexible. One should be aware of the
%D fact that the offsets depend on the design of the glyphs 
%D used. 

\def\DroppedCaps#1#2#3#4#5#6#7%
  {\par
   \vskip#6\baselineskip
   \penalty-200
   \vskip-#6\baselineskip
   \setbox0=\hbox
     {\definefont[temp][#2 at #3]%
      \temp#1{#7}\hskip#4}%
   \setbox0=\hbox
     {\lower#5\box0}%
   \ht0=\ht\strutbox
   \dp0=\dp\strutbox
   \hangindent\wd0
   \hangafter-#6%
   \noindent
   \hskip-\wd0
   \vbox{\forgetall\box0}%
   \nobreak}

%D Before we go to the next topic, we summarize this command:
%D
%D \starttypen
%D \DroppedCaps 
%D    {command} {font} 
%D    {height} {hoffset} {voffset} {lines}
%D \stoptypen

%D \macros
%D   {TreatFirstLine}
%D
%D \startbuffer
%D \TreatFirstLine {\sc} {} {} {}
%D Instead of limiting its action to one token, the next macro
%D treats the whole first line. This paragraph was typeset by
%D saying:
%D \stopbuffer
%D
%D \haalbuffer
%D
%D \typebuffer
%D
%D \startbuffer
%D \TreatFirstLine {\startcolor[red]\bf} {\stopcolor} {} {}
%D The combined color and font effect is also possible,
%D although one must be careful in using macros that accumulate
%D grouping, but the commands used here are pretty save in that
%D respect.
%D \stopbuffer
%D
%D \haalbuffer
%D
%D \typebuffer
%D 
%D Before we explain the third and fourth argument, we show the
%D implementation. Those who know a bit about the way \TEX\ 
%D treats tokens, will probably see in one glance that this
%D alternative works all right for most text||only situations
%D in which there is enough text available for the first line,
%D but that more complicated things will blow. One has to live
%D with that. A workaround is rather trivial but obscures the
%D principles used. 

\def\TreatFirstLine#1#2#3#4% before, after, first, next
  {\leavevmode
   \bgroup
   \forgetall
   \bgroup
   #1%
   \setbox0=\box\voidb@x
   \setbox2=\box\voidb@x
   \def\grabfirstline##1 %
     {\setbox2=\hbox
        {\ifvoid0
           {#3{\ignorespaces##1}}%
         \else
           \unhcopy0\ {#4{##1}}%
         \fi}%
      \ifdim\wd2=\!!zeropoint
        \setbox0=\box\voidb@x
        \setbox2=\box\voidb@x
        \let\next=\grabfirstline
      \else\ifdim\wd2>\hsize
        \hbox to \hsize{\strut\unhbox0}#2\egroup
        \break##1\ 
        \egroup
        \let\next=\relax
      \else
        \setbox0=\box2
        \let\next=\grabfirstline
      \fi\fi
      \next}%
   \grabfirstline}

%D \startbuffer
%D \gdef\FunnyCommand
%D   {\getrandomfloat\FunnyR{0}{1}%
%D    \getrandomfloat\FunnyG{0}{1}%
%D    \getrandomfloat\FunnyB{0}{1}%
%D    \definecolor[FunnyColor][r=\FunnyR,g=\FunnyG,b=\FunnyB]%
%D    \color[FunnyColor]}
%D 
%D \TreatFirstLine {\bf} {} {\FunnyCommand} {\FunnyCommand}
%D The third and fourth argument can be used to gain special 
%D effects on the individual words. Of course one needs ...
%D \stopbuffer
%D 
%D \haalbuffer 
%D to know a bit more about the macro package used to get real 
%D nice effects, but this example probably demonstrates the 
%D principles well. 
%D 
%D \typebuffer
%D 
%D Like in dropped caps case, one can hide such treatments in a
%D macro, like:
%D
%D \starttypen
%D \def\MyTreatFirstLine%
%D   {\TreatFirstLine{\bf}{}{\FunnyCommand}{\FunnyCommand}}
%D \stoptypen

%D \macros 
%D   {reshapebox}
%D 
%D \startbuffer 
%D \beginofshapebox
%D When using \CONTEXT, one can also apply this funny command 
%D to whole lines by using the reshape mechanism. Describing 
%D this interesting mechanism falls outside the scope of this 
%D module, so we only show the trick. This is an example of 
%D low level \CONTEXT\ functionality: it's all there, and it's 
%D stable, but not entirely meant for novice users. 
%D \endofshapebox
%D 
%D \reshapebox{\FunnyCommand{\box\shapebox}} \flushshapebox
%D \stopbuffer
%D 
%D \haalbuffer
%D 
%D \typebuffer
%D
%D This mechanism permits hyphenation and therefore gives 
%D better results than the previously discussed macro 
%D \type{\TreatFirstLine}. 

%D \macros
%D   {TreatFirstCharacter}
%D
%D \startbuffer
%D \TreatFirstCharacter{\bf\color[green]} Just to be 
%D \stopbuffer
%D
%D \haalbuffer complete we also offer a very simple one 
%D character alternative, that is not that hard to understand:

\def\TreatFirstCharacter#1#2% command, character
  {{#1{#2}}}

%D A previous paragraph started with:
%D
%D \typebuffer

%D \macros
%D   {StackCharacters}
%D
%D The next hack deals with vertical stacking.

\def\StackCharacters#1#2#3#4% sequence vsize vskip command
  {\vbox #2
     {\forgetall
      \baselineskip0pt
      \def\StackCharacter##1{#4{##1}\cr\noalign{#3}}%
      \halign
        {\hss##\hss&##\cr
         \handletokens#1\with\StackCharacter\cr}}}

%D \startbuffer
%D \StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}
%D \stopbuffer
%D 
%D Such a stack looks like:
%D 
%D \startregelcorrectie
%D \hbox to \hsize
%D    {$\hss\bfd
%D     \vcenter{\StackCharacters{TEX}    {}{\vskip.2ex}{\FunnyCommand}}%
%D     \hss
%D     \vcenter{\StackCharacters{CON}    {}{\vskip.2ex}{\FunnyCommand}}
%D     \hss
%D     \vcenter{\StackCharacters{TEXT}   {}{\vskip.2ex}{\FunnyCommand}}
%D     \hss
%D     \vcenter{\StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}}
%D     \hss$}
%D \stopregelcorrectie
%D 
%D and is typeset by saying:
%D
%D \typebuffer
%D
%D An alternative would have been
%D
%D \starttypen
%D \StackCharacters {CONTEXT} {to 5cm} {\vfill} {\FunnyCommand}
%D \stoptypen

%D \macros
%D   {processtokens}
%D
%D At a lower level horizontal and vertical manipulations are
%D already supported by:
%D
%D \starttypen
%D \processtokens {begin} {between} {end} {space} {text}
%D \stoptypen
%D
%D \startbuffer[a]
%D \processtokens 
%D   {\hbox to .5\hsize\bgroup} {\hfill} 
%D   {\egroup} {\space} {LET'S HAVE}
%D \stopbuffer
%D  
%D \startbuffer[b]
%D \processtokens 
%D   {\vbox\bgroup\raggedcenter\hsize1em} 
%D   {\vskip.25ex} {\egroup} {\strut} {FUN}
%D \stopbuffer
%D
%D This macro is able to typeset: 
%D
%D \leavevmode\hbox to \hsize
%D   {$\hfil\hfil
%D    \vcenter{\bf\haalbuffer[a]}%
%D    \hfil
%D    \vcenter{\bfd\haalbuffer[b]}%
%D    \hfil\hfil$}
%D
%D which was specified as:
%D
%D \typebuffer[a]
%D \typebuffer[b]

%D \macros
%D   {NormalizeFontHeight, NormalizeFontWidth, 
%D    TheNormalizedFontSize}
%D
%D Next we introduce some font manipulation macros. When we
%D want to typeset some text spread in a well defined area, it
%D can be considered bad practice to manipulate character and
%D word spacing. In such situations the next few macros can be
%D of help: 
%D 
%D \starttypen
%D \NormalizeFontHeight \name {sample text} {height} {font}
%D \NormalizeFontWidth  \name {sample text} {width}  {font}
%D \stoptypen
%D 
%D These are implemented using an auxilliary macro:

\def\NormalizeFontHeight%
  {\NormalizeFontSize\ht}

\def\NormalizeFontWidth%
  {\NormalizeFontSize\wd} 

\def\NormalizeFontSize#1#2#3#4#5%
  {\bgroup
   \dimen0=#4% #4 can be \ht0 or so
   \setbox0=\hbox{\definefont[temp][#5 at 10pt]\temp#3}%
   \dimen2=#10 % #1 is \wd or \ht
   \dimen4=10000pt
   \divide\dimen4 by \dimen2
   \divide\dimen0 by 1000
   \dimen0=\number\dimen4\dimen0
   \xdef\TheNormalizedFontSize{\the\dimen0}%
   \definefont[temp][#5 at \the\dimen0]%
   \temp
   \expandafter
   \egroup
   \expandafter\font\expandafter#2\expandafter=\fontname\font\relax}

%D Afterwards, we have access to the calculated size by: 

\let\TheNormalizedFontSize\!!zeropoint

%D Consider for instance:
%D 
%D \startbuffer
%D \NormalizeFontHeight \tmp {X} {2\baselineskip} {cmr10}
%D 
%D {\tmp To Be Or Not To Be}
%D \stopbuffer
%D 
%D \typebuffer
%D 
%D This shows up as (we also show the baselines):
%D  
%D {\showbaselines\haalbuffer}
%D 
%D The horizontal counterpart is:
%D 
%D \startbuffer
%D \NormalizeFontWidth \tmp {This Line Fits} {\hsize} {cmr10}
%D 
%D \hbox{\tmp This Line Fits}
%D \stopbuffer
%D 
%D \typebuffer
%D 
%D The calculated font scale is avaliable in the macro 
%D \type{\NormalizedFontSize}. 
%D
%D \startregelcorrectie
%D \ruledhbox{\haalbuffer}
%D \stopregelcorrectie
%D
%D One can of course combine these macros with the ones 
%D described earlier, like in:
%D 
%D \starttypen
%D \NormalizeFontHeight {text} \DroppedFont {2\baselineskip} {cmbx12}
%D 
%D \def\NicelyDroppedCaps%
%D   {\DroppedCaps 
%D      {\kleur[groen]} 
%D      {\DroppedFont} 
%D      {2pt} 
%D      {\baselineskip} 
%D      {2}}
%D \stoptypen
%D
%D It's up to the reader to test this one. 

\protect

\endinput
