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
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Module: Letterspacing Facility
%
% Synopsis: This module provides a fairly comprehensive letterspacing
% facility for ZzTeX.
%
% Author: Paul C. Anagnostopoulos
% Created: 10 July 1997
%
% Copyright 1989--2020 by Paul C. Anagnostopoulos
% under The MIT License (opensource.org/licenses/MIT)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Letterspacing Commands
% ------------- --------
\defineskip{\zlspamount}{0pt}
\defineskip{\zlspace}{0pt}
\def \letterspace #1#2{% {amount[,space]}{text}
{\zlspparse #1,,\zmark
\zletterspace{#2}}}
\def \eletterspace #1#2{% {amount[,space]}{text}
\edef \znext {\noexpand\letterspace{#1}{#2}}%
\znext}
\def \zlspparse #1,#2,#3\zmark{%
\zlspamount = #1\relax
\if \emptyargp{#2}%
\measurespacewidth{\zlspace}%
\advance \zlspace by \zlspamount
\else
\zlspace = #2\relax
\fi}
% These commands can be used in letterspaced text, but must do nothing
% when letterspacing is not in progress.
\let \lsp = \relax
\let \nolsp = \relax
\def \lspspace {\space}%
\def \zlspoff {\relax}%
\def \lspoff {\zlspoff}%
\def \zlspon {\relax}%
\def \lspon {\zlspon}%
% Letterspacing Engine
% ------------- ------
\def \zletterspace #1{% {text}
\def \lsp {\nobreak\hskip \zlspamount}%
\def \lspspace {\hskip \zlspace}%
\def \zzlspoff {\zlspoff}%
\def \zzlspon {\zlspon}%
\setflag \zlsping = \true
\let \zlspprev = \relax
\setflag \zlspprevchar = \false
\let \zmark = \relax
{\zlspa #1\zmark}}
\def \zlspa {\futurelet\zlspcur \zlspb}
\def \zlspb {%
\let \znext = \zlspc
\if \tokeqlp{\zlspcur}{\zmark}%
\let \znext = \relax
\else\if \cateqlp{\noexpand\zlspcur}{\zspacetoken}%
\if \zlsping \aftergroup\lspspace \else \aftergroup\space \fi
\else\if \cateqlp{\noexpand\zlspcur}{\bgroup}%
\aftergroup{%
\else\if \cateqlp{\noexpand\zlspcur}{\egroup}%
\aftergroup}%
\else\if \tokeqlp{\zlspcur}{\zzlspoff}%
\setflag \zlsping = \false
\else\if \tokeqlp{\zlspcur}{\zzlspon}%
\setflag \zlsping = \true
\else
\let \znext = \zlspd
\fi\fi\fi\fi\fi\fi
\znext}
\def \zlspc {% Discard current token.
\let \zlspprev = \zlspcur
\setflag \zlspprevchar = \false
\afterassignment\zlspa \let\zlspcur = }
\long\def \zlspd #1{% Process current token.
\let \zlspprev = \zlspcur
\if \cateqlp{\noexpand#1}{\relax}%
\setflag \zlspprevchar = \false
\aftergroup#1%
\else\if \cateqlp{\noexpand#1}{\noexpand~}%
\setflag \zlspprevchar = \false
\if \zlsping \aftergroup\lspspace \else \aftergroup\space \fi
\else\if \orp{\andp{\codeeqlp{\zlspprev}{-}}{\codeeqlp{\zlspcur}{-}}}
{\orp{\andp{\codeeqlp{\zlspprev}{`}}{\codeeqlp{\zlspcur}{`}}}
{\andp{\codeeqlp{\zlspprev}{'}}{\codeeqlp{\zlspcur}{'}}}}%
\setflag \zlspprevchar = \true
\aftergroup#1%
\else
\if \andp{\zlspprevchar}{\zlsping}\aftergroup\lsp \fi
\setflag \zlspprevchar = \true
\aftergroup#1%
\fi\fi\fi
\zlspa}
|