% \iffalse %% File: soul-ori.dtx % Copyright (C) 1998--2003 Melchior FRANZ % Copyright (C) 2021-2023 Oberdiek Package Support Group % https://github.com/ho-tex/soul/issues % % COPYRIGHT NOTICE: % This package is free software that can be redistributed and/or modified % under the terms of the LaTeX Project Public License as specified % in the file macros/latex/base/lppl.txt on any CTAN archive server, % such as ftp://ftp.dante.de/. % %% Original author data: %% ==================================================================== %% @LaTeX-package-file{ %% author = "Melchior FRANZ", %% version = "2.4", %% date = "17 November 2003", %% filename = "soul.dtx", %% address = "Melchior FRANZ %% Rieder Hauptstrasse 52 %% A-5212 SCHNEEGATTERN %% AUSTRIA", %% telephone = "++43 7746 3109", %% URL = "http://www.unet.univie.ac.at/~a8603365/", %% email = "a8603365@unet.univie.ac.at", %% codetable = "ISO/ASCII", %% keywords = "spacing out, letterspacing, underlining, striking out, %% highlighting", %% supported = "yes", %% docstring = "This article describes the `soul' package, which %% provides hyphenatable letterspacing (spacing out), %% underlining, and some derivatives. %% All features are based upon a common mechanism %% that allows to typeset text syllable by syllable, %% where the excellent TeX hyphenation algorithm is %% used to find the proper hyphenation points. %% Two examples show how to use the provided interface to %% implement things such as `an-a-lyz-ing syl-la-bles'. %% Although the package is optimized for LaTeX2e, %% it works with Plain TeX and with other %% packages, too.", %% } %% ==================================================================== % % % % % %<*driver> \def\fileversion{3.0} \def\filedate{2023-18-02} % \documentclass{ltxdoc} % % % \makeatletter\let\SOUL@sethyphenchar\relax\makeatother \IfFileExists{soul.sty}{% \usepackage{soul}[2002/01/10] \expandafter\ifx\csname sloppyword\endcsname\relax % old version? \def\sloppyword{\textbf{?? [obsolete soul version]}} \fi \let\SOULSTYfound\active }{% \GenericWarning{soul.dtx}{% Package file `soul.sty' couldn't be found. You should however find^^J^^A a file `soul.ins' in the current directory. If you type "tex soul.ins"^^J^^A on the command line, `soul.sty' will be generated. After that run "latex soul.dtx" again and you won't see this message again. }% }% % % % \usepackage{hyperref} \hypersetup{ bookmarksopen, colorlinks, pdftitle={The soul-ori package}, pdfauthor={Melchior FRANZ}, pdfsubject={Version 3.0}, pdfkeywords={space out, letterspacing, underlining, overstriking, highlighting} } \usepackage{graphicx,color} \pdfstringdefDisableCommands{% \let\so\relax \let\caps\relax \let\ul\relax \let\st\relax \let\hl\relax \def\soul{soul}% \def\TeX{TeX}} % % % %\RecordChanges % \begin{document} \setcounter{tocdepth}{2} \DocInput{soul-ori.dtx} \end{document} % % \fi % % \title{The \texttt{soul-ori} package} % % \author{Melchior \caps{FRANZ}} % % \date{November 17, 2003} % %^^A===================================================== % %^^A These messy macros allow to typeset the `example' sections %^^A conveniently. You'd better ignore them. I do! :-) % % \makeatletter % % \def\squarebull{\rule[.2ex]{.8ex}{.8ex}} % % \newenvironment{examples} % {\parindent\z@\small\fontencoding{OT1}\selectfont} % {\rule{\hsize}{.4pt}} % % \def\soultest#1|{\bgroup\rule[.5ex]{\hsize}{.4pt}\par % \parbox[t]{.34\hsize}{\raggedright\textit{#1\unskip.}}% % \hspace{1.5em}$\vtop\bgroup\hb@xt@.4\hsize\bgroup % \llap{\squarebull\hspace{.4em}}\soulttest} % % {\catcode`\|=13\gdef\soulttest{% % \bgroup\def\do##1{\catcode`##1=12}\dospecials\ttfamily % \catcode`\|=13\unskip\def|{\hss\egroup\egroup\soultttest}}} % % \def\soultttest#1{\hbox{\vtop{\hsize.4\hsize\hbadness\@M % \leavevmode\llap{\squarebull\hspace{.4em}}#1\null}}% % \egroup$\hspace{1.5em}\parbox[t]{1mm}{\hyphenpenalty-\@M % \exhyphenpenalty-\@M\hbadness\@M\hfuzz\maxdimen % \strut\llap{\squarebull\hspace{.4em}}#1\null}% % \goodbreak\vspace{2ex} % \egroup} % % \newcommand*\DescribeOption[1]{\marginpar{\raggedleft\textsf{#1}\ignorespaces}} % % %^^A similar to the `description' environment % % \def\describemacro{^^A % \bgroup % \let\do\@makeother % \dospecials % \catcode`{=1 % \catcode`}=2 % \SOUL@@@descmacro % } % % \def\SOUL@@@descmacro#1{^^A % \texttt{#1}^^A % \DescribeMacro{#1}^^A % \expandafter\edef\expandafter\x\expandafter{\expandafter\@gobble#1}^^A % \expandafter\label{cmd:\x}^^A % \egroup % } % % % \def\SOUL@@@verbitem[#1: {^^A % \bgroup % \let\do\@makeother % \dospecials % \SOUL@@@verbscan{#1}^^A % } % % \def\SOUL@@@verbscan#1#2]{^^A % \egroup % \goodbreak % \def\@currentlabel{\S\,\the\SOUL@@@itemnr}^^A % \label{par:#1}^^A % \SOUL@@@item[\textbf{\@currentlabel\hskip.6em#1:}]\hfil\break % Example: \texttt{#2}\hfil\break^^A % \advance\SOUL@@@itemnr1 % } % % \let\SOUL@@@item\item % \newcount\SOUL@@@itemnr % % \newenvironment{verblist}[1]{^^A % \SOUL@@@itemnr=#1 % \list{}{^^A % \settowidth{\labelwidth}{\indent\indent}^^A % \leftmargin\labelwidth % \advance\leftmargin\labelsep % \def\makelabel##1{##1}^^A % \let\item\SOUL@@@verbitem % }^^A % }{^^A % \endlist % } % % \newenvironment{labeling}[1]{^^A % \list{}{^^A % \settowidth{\labelwidth}{\textbf{#1}}^^A % \leftmargin\labelwidth\advance\leftmargin\labelsep % \def\makelabel##1{\textbf{##1}\hfil}^^A % }^^A % }{^^A % \endlist % } % % \newenvironment{syntax}{^^A % \par\medskip\def\<##1>{$\langle$\syn{##1}$\rangle$}^^A % \indent\begin{tabular}{l}^^A % }{^^A % \end{tabular}^^A % \noindentafter\medbreak % } % % % \newenvironment{example}[1][.9\textwidth] % {\par\medskip\indent\begin{tabular}{p{#1}l}} % {\end{tabular}\noindentafter\medbreak} % % \newcommand*\noindentafter{^^A % \global\everypar{{\setbox\z@\lastbox}\everypar{}}} % % \newcommand*\errsquare{\leavevmode\vrule height.8em depth.2em width1em\relax} % % % \ifx\SOULSTYfound\active %^^A analyze syllables---described somewhere below % % \DeclareRobustCommand*\sy{^^A % \SOUL@setup % \def\SOUL@preamble{\lefthyphenmin0\righthyphenmin0}^^A % \def\SOUL@everysyllable{\the\SOUL@syllable}^^A % \def\SOUL@everyspace##1{##1\space}^^A % \def\SOUL@everyhyphen{^^A % \discretionary{^^A % \SOUL@setkern\SOUL@hyphkern % \SOUL@sethyphenchar % }{}{^^A % \hbox{\kern1pt$\cdot$}^^A % }^^A % }^^A % \def\SOUL@everyexhyphen##1{^^A % \SOUL@setkern\SOUL@hyphkern % \hbox{##1}^^A % \discretionary{}{}{^^A % \SOUL@setkern\SOUL@charkern % }^^A % }^^A % \SOUL@} % %^^A analyze the engine---described somewhere below, too % % \DeclareRobustCommand*\an{^^A % \def\SOUL@preamble{$^{^P}$}^^A % \def\SOUL@everyspace##1{##1\texttt{\char`\ }}^^A % \def\SOUL@postamble{$^{^E}$}^^A % \def\SOUL@everyhyphen{$^{^-}$}^^A % \def\SOUL@everyexhyphen##1{##1$^{^=}$}^^A % \def\SOUL@everysyllable{$^{^S}$}^^A % \def\SOUL@everytoken{\the\SOUL@token$^{^T}$}^^A % \def\SOUL@everylowerthan{$^{^L}$}^^A % \SOUL@} % %^^A magazine-like (truly awful) paragraphs %^^A If you know what you're doing, you can copy it to your personal `soul.cfg' file. % % \DeclareRobustCommand*\magstylepar{\SOUL@sosetup % \def\SOUL@preamble{^^A % \edef\SOUL@soletterskip{\z@\@plus\fontdimen2\font\@minus\z@}^^A % \edef\SOUL@soinnerskip{\the\fontdimen2\font % \@plus\the\fontdimen3\font\@minus\the\fontdimen4\font}^^A % \let\SOUL@soouterskip\SOUL@soinnerskip % \SOUL@sopreamble}^^A % \lefthyphenmin2\righthyphenmin2\SOUL@} % %\else % %^^A The package has not been found, so we're providing some dummies, just %^^A to avoid all these `Undefined command sequence' messages. % % \def\SOUL@@@X#1{\textbf{??}}% % \let\so\SOUL@@@X % \let\textso\SOUL@@@X % \let\caps\SOUL@@@X % \let\textcaps\SOUL@@@X % \let\ul\SOUL@@@X % \let\textul\SOUL@@@X % \let\st\SOUL@@@X % \let\textst\SOUL@@@X % \let\hl\SOUL@@@X % \let\texthl\SOUL@@@X % \let\sy\SOUL@@@X % \let\an\SOUL@@@X % \let\magstylepar\SOUL@@@X % \let\sloppyword\SOUL@@@X % \def\sodef#1#2#3#4{\let#1\relax\SOUL@@@X}% % \fi % % \newcommand*\xpath{^^A % \bgroup % \let\do\@makeother % \dospecials % \catcode`\{=1 % \catcode`\}=2 % \def\{{\char"7B}^^A % \def\}{\char"7D}^^A % \SOUL@@@code % } % % \newcommand*\SOUL@@@code[1]{\normalfont\texttt{#1}\egroup} % % \let\cs\xpath % \let\option\textsf % \def\package#1{{\normalfont\texttt{#1}}} % \let\program\texttt % \let\bibtitle\textit % \let\syn\textit % % \sodef\person{\scshape}{0.06em}{0.45em}{0.4em} % \sodef\SOUL@@@versal{\upshape}{0.125em}{0.4583em}{0.5833em} % \DeclareRobustCommand*\versal[1]{^^A % \MakeUppercase{\SOUL@@@versal{#1}}^^A % } % % \def\ConTeXt{Con\TeX t} % \def\CTAN{{\small\caps{CTAN}}} % \def\soul{\package{soul-ori}} % % ^^A set some parameters as used in Plain TeX % \def\plainsetup{^^A % \pretolerance100 % \tolerance200 % \hbadness1000 % \linepenalty10 % \hyphenpenalty50 % \exhyphenpenalty50 % \doublehyphendemerits10000 % \finalhyphendemerits5000 % \adjdemerits10000 % \hfuzz.1pt % \overfullrule5pt % } % % \def\FIXME#1{\message{}#1} % % \makeatother % % % \lefthyphenmin2 % \righthyphenmin3 % \hyphenation{Le-se-ty-po-gra-phie Ver-bin-dung fak-si-mi-le} % % %^^A===================================================== % % % \changes{v1.0}{1998/10/16}{Initial version}% %^^A due to an error in the documentation of v1.0, there's no v1.1 :-( % \changes{v1.1a}{1998/12/08}{fixed a bunch of bugs; `magstylepar command % banned; `caps introduced; `so and `caps recognize following spaces; % error message added; `so parameters are mandatory} % % \changes{v1.2}{1999/01/11}{fixed the newline bug; added the `\(>\) command} % % \changes{v1.3}{1999/05/15}{changed allowhyphen, preambles; added a paragraph % in the `features' section} % % \changes{v2.0}{2002/01/03}{(almost) complete rewrite} % % \changes{v2.1}{2002/01/10}{Happy (64th) birthday, Don! % ``The now-traditional fix for the % now-traditional brown-paper-bag major release.'' % as Eric S. RAYMOND commented on his CML2.0.1 release. ;-)} % % \changes{v2.2}{2002/05/12}{fixed a couple of bugs; added support for % the Plain TeX color.sty wrapper} % % \changes{v2.3}{2002/05/29}{compatibility with cmbright/ccfonts} % % \changes{v2.4}{2003/11/17}{Fix the font bug. Fix a scanner bug. % Other bugfixes; change caps set handling; add footnote and % textsuperscript support} % % \changes{v2.5}{2021/12/14}{Allocate new registers, see issue 1 +2 at https://github.com/drehscheibe/soul, % renamed to soul-ori, to allow to merge it with soulutf8} % % \changes{v3.0}{2023/02/18}{the package has been merged with soulutf8} % % % % \maketitle % % % % \begin{abstract} % This article describes the \soul\ package^^A %^^A%% % \footnote{This file has version number \fileversion, last revised \filedate.}, %^^A%% % which provides \so{hyphenatable letterspacing (spacing out),} \ul{underlining} % and some derivatives such as \st{overstriking} and highlighting. % Although the package is optimized for \LaTeXe, it also works with % Plain \TeX\ and with other flavors of \TeX\ like, for instance, \ConTeXt. % By the way, the package name |soul| is only a combination % of the two macro names \cs{\so} (space out) and \cs{\ul} % (underline)---nothing poetic at all.^^A :-( % \end{abstract} % % % {\setlength\parskip{0pt}\tableofcontents } % \addtocontents{toc}{\protect\begin{multicols}{2}} % % % % % % % % % % \section{Typesetting rules} % \label{sec:typesetting} % % There are several possibilities to emphasize parts of a paragraph, % not all of which are considered good style. While underlining % is commonly rejected, experts dispute about whether letterspacing % should be used or not, and in which cases. If you are not interested % in such debates, you may well skip to the next section. % % % \subsection*{Theory \dots} % \label{sec:theory} % % To understand the experts' arguments we have to know about the % conception of \emph{page grayness.} The sum of all characters on % a page represents a certain amount of grayness, provided that % the letters are printed black onto white paper. % % \person{Jan Tschichold} \cite{Tschichold}, a well known and recognized % typographer, accepts only forms of emphasizing, which do not disturb this % grayness. This is only true of italic shape, caps, and % caps-and-small-caps fonts, but not of ordinary letterspacing, underlining, % bold face type and so on, all of which appear as either dark or light % spots in the text area. In his opinion emphasized text shall not catch the eye when % running over the text, but rather when actually reading the respective words. % % Other, less restrictive typographers \cite{Willberg} call this kind of emphasizing % `integrated' or `aesthetic', while they describe `active' emphasizing apart from it, % which actually \emph{has} to catch the reader's eye. To the latter group belong commonly % despised things like letterspacing, demibold face type and even underlined and colored text. % % On the other hand, \person{Tschichold} suggests % to space out caps and caps-and-small-caps fonts on title pages, headings and running headers from % 1\,pt up to 2\,pt. % Even in running text legibility of uppercase letters should be improved with slight % letterspacing, since (the Roman) majuscules don't look right, if they are spaced % like (the Carolingian) minuscules.\footnote{This suggestion is followed throughout this article, % although Prof.~\person{Knuth} already considered slight letterspacing with his |cmcsc| fonts.} % % % %\subsection*{\dots\ and Practice} % % However, in the last centuries letterspacing was excessively used, % underlining at least sometimes, because capitals and italic shape could % not be used together with the \emph{Fraktur} font and other black-letter fonts, % which are sometimes also called ``old German'' fonts. % This tradition is widely continued until today. The same limitations apply still today % to many languages with non-latin glyphs, which is why letterspacing has a strong % tradition in eastern countries where Cyrillic fonts are used. % % The \person{Duden} \cite{Duden}, a well known German dictionary, explains how to space out properly: % \emph{Punctuation marks are spaced out like letters, except quotation marks and periods. % Numbers are never spaced out. The German syllable \mbox{\emph{-sche}} is not spaced % out in cases like \emph{``der {\so{Virchow{sche}}} Versuch''}\footnote{the \person{Virchow} experiment}. % In the old German \emph{Fraktur} fonts the ligatures \emph{|ch|, |ck|, |sz|~(\ss)} and~\emph{|tz|} are % not broken within spaced out text.} % % While some books follow all these rules \cite{Muszynski}, others don't % \cite{Reglement}. In fact, most books in my personal library do \emph{not} space out commas. % % % % % % % % % % \section{Short introduction and common rules} % % The \soul\ package provides five commands that are aimed at emphasizing % text parts. Each of the commands takes one argument that can either be % the text itself or the name of a macro that contains text (e.\,g.~|\so\text|)^^A % ^^A % \footnote{See~\ref{par:Unexpandable material in command sequences} for % some additional information about the latter mode.}^^A % ^^A % . % See table~\ref{tab:survey} for a complete command survey. % % {\catcode`\|=12 % \begin{center} % \begin{tabular}{r@{\hspace{1.5em}}l} % \verb+\so{letterspacing}+&\so{letterspacing}\\ % \verb+\caps{CAPITALS, Small Capitals}+&\caps{CAPITALS, Small Capitals}\\ % \verb+\ul{underlining}+&\ul{underlining}\\ % \verb+\st{overstriking}+&\st{overstriking}\\ % \verb+\hl{highlighting}+&highlighting\footnotemark\\ % \end{tabular} % \end{center} % \footnotetext{The look of highlighting is nowhere demonstrated % in this documentation, because it requires a Postscript aware % output driver and would come out as ugly black bars on other % devices, looking very much like censoring bars. Think of it as % the effect of one of those coloring text markers.} % } % % \noindent % The \cs{\hl} command does only highlight if the \package{color} package % was loaded, otherwise it falls back to underlining.\footnote{Note that % you can also use \LaTeX's \package{color} package with Plain \TeX. % See~\ref{sec:plain} for details.} The highlighting % color is by default yellow, underlines and overstriking lines are by % default black. The colors can be changed using the following commands: % % {\catcode`\|=12 % \begin{center} % \begin{tabular}{r@{\hspace{1.5em}}l} % \verb+\setulcolor{red}+&set underlining color\\ % \verb+\setstcolor{green}+&set overstriking color\\ % \verb+\sethlcolor{blue}+&set highlighting color\\ % \end{tabular} % \end{center} % } % % \noindent % |\setulcolor{}| and |\setstcolor{}| turn coloring off. % There are only few colors predefined by the \package{color} % package, but you can easily add custom color definitions. % See the \package{color} package documentation~\cite{color} for further % information. % % \begin{example} % |\usepackage{color,soul}|\\ % |\definecolor{lightblue}{rgb}{.90,.95,1}|\\ % |\sethlcolor{lightblue}|\\ % |...|\\ % |\hl{this is highlighted in light blue color}|\\ % \end{example} % % % % % % % % \subsection[Some things work]{Some things work \dots} % % The following examples may look boring and redundant, because they describe % nothing else than common \LaTeX\ notation with a few exceptions, but this is % only the half story: The \soul\ package has to pre-process the argument % before it can split it into characters and syllables, and all described % constructs are only allowed because the package explicitly implements them. % % \begin{verblist}{1} % \item[Accents: \so{na\"\i ve}] % Accents can be used naturally. % Support for the following accents is built-in: |\`|, |\'|, |\^|, |\"|, |\~|, % |\=|, |\.|, |\u|, |\v|, |\H|, |\t|, |\c|, |\d|, |\b|, and |\r|. Additionally, % if the \package{german} package \cite{german} is loaded you can also use the |"| % accent command and write |\so{na"ive}|. See section~\ref{sec:soulaccent} for how to add % further accents. % \item[Quotes: \so{``quotes''}] % The \soul\ package recognizes the quotes ligatures |``|, |''| and |,,|. % The Spanish ligatures |!`| and |?`| are not recognized and have, thus, % to be written enclosed in braces like in |\caps{{!`}Hola!}|. % \item[Mathematics: \so{foo$x^3$bar}] % Mathematic formulas are allowed, as long as they are % surrounded by~\texttt\$. Note that the \LaTeX\ % equivalent |\(...\)| does not work. % \item[Hyphens and dashes: \so{re-sent}] % Explicit hyphens as well as en-dashes~(|--|), em-dashes~(|---|) % and the |\slash| command work as usual. % \item[Newlines: \so{new\\line}] % The |\\|~command fills the current line with white space % and starts a new line. Spaces or linebreaks afterwards are ignored. % Unlike the original \LaTeX\ command \soul's version does not handle % optional parameters like in |\\*[1ex]|. % \item[Breaking lines: \so{foo\linebreak bar}] % The \cs{\linebreak} command breaks the line without % filling it with white space at the end. \soul's version % does not handle optional parameters like in |\linebreak[1]|. % \cs{\break} can be used as a synonym. % \item[Unbreakable spaces: \so{don't~break}] % The |~|~command sets an unbreakable space. % \item[Grouping: \so{Virchow{sche}}] % A pair of braces can be used to let a group of characters % be seen as one entity, so that \soul\ does % for instance not space it out. The contents must, however, % not contain potential hyphenation points. (See~\ref{par:Protecting}) % \item[Protecting: \so{foo \mbox{little} bar}] % An \cs{\mbox} also lets \soul\ see the contents as one % item, but these may even contain hyphenation points. \cs{\hbox} can % be used as a synonym. % \item[Omitting: \so{\soulomit{foo}}] % The contents of \cs{\soulomit} bypass the soul core and are typeset % as is, without being letterspaced or underlined. Hyphenation points are % allowed within the argument. The current font remains active, but can be % overridden with \cs{\normalfont} etc. % \item[Font switching commands: \so{foo \texttt{bar}}] % All standard \TeX\ and \LaTeX\ font switching commands are allowed, as % well as the \package{yfonts} package \cite{yfonts} font commands like \cs{\textfrak} etc. % Further commands have to be registered using the \cs{\soulregister} % command (see section~\ref{sec:soulregister}). % \item[Breaking up ligatures: \ul{Auf{}lage}] % Use |{}| or \cs{\null} to break up ligatures like `fl' in \cs{\ul}, \cs{\st} and \cs{\hl} % arguments. % This doesn't make sense for \cs{\so} and \cs{\caps}, though, because they break up % every unprotected (ungrouped\slash unboxed) ligature, anyway, and would % then just add undesirable extra space around the additional item. % \end{verblist} % % % % % \subsection{\dots\ others don't} % % Although the new \soul\ is much more robust and forgiving than % versions prior to~2.0, there are % still some things that are not allowed in arguments. % This is due to the complex engine, which has to read and inspect every % character before it can hand it over to \TeX's paragraph builder. % % \begin{verblist}{20} % \item[Grouping hyphenatable material: \so{foo {little} bar}] % Grouped characters must not contain hyphenation points. Instead of % |\so{foo {little}}| write |\so{foo \mbox{little}}|. You get a % \texttt{`Re\-con\-struction failed'} error and a black square like % \errsquare\ in the \caps{DVI} file where you violated this rule. % \item[Discretionary hyphens: \so{Zu\discretionary{k-}{}{c}ker}] % The argument must not contain discretionary hyphens. Thus, you have to % handle cases like the German word |Zu\discretionary{k-}{}{c}ker| by yourself. % \item[Nested soul commands: \ul{foo \so{bar} baz}] % \soul\ commands must not be nested. If you really % need such, put the inner stuff in a box and use this box. It will, of % course, not get broken then.\\ % \null\qquad|\newbox\anyboxname|\\ % \null\qquad|\sbox\anyboxname{ \so{the worst} }|\\ % \null\qquad|\ul{This is by far{\usebox\anyboxname}example!}|\\ % yields:\\ % \newbox\anyboxname % \sbox\anyboxname{ \so{the worst} } % \null\qquad\ul{This is by far{\usebox\anyboxname}example!} % \item[Leaking font switches: \def\foo{\bf bar} \so{\foo baz}] % A hidden font switching command that leaks into its neighborship % causes a \texttt{`Reconstruction failed'} error. To avoid this either % register the `container' (|\soulregister{\foo}{0}|), or limit its % scope as in |\def\foo{{\bf bar}}|. Note that both % solutions yield slightly different results. % \item[Material that needs expansion: \so{\romannumeral\year}] % In this example \cs{\so} would try to put space between \cs{\romannumeral} % and \cs{\year}, which can, of course, not work. % You have to expand the argument before you feed it to \soul, or even better: % Wrap the material up in a command sequence and let \soul\ expand it: % |\def\x{\romannumeral\year}| |\so\x|. \soul\ tries hard to expand % enough, yet not too much. % \item[Unexpandable material in command sequences: \def\foo{\bar} \so\foo] % Some macros might not be expandable in an \cs{\edef} definition^^A % \footnote{Try \texttt{\string\edef\string\x\char`\{\string\copyright\char`\}}. % Yet \texttt{\string\copyright} works in \soul\ arguments, because it is % explicitly taken care of by the package} % and have to be protected with \cs{\noexpand} in front. This is automatically done % for the following tokens: |~|, \cs{\,}, \cs{\TeX}, \cs{\LaTeX}, % \cs{\S}, \cs{\slash}, \cs{\textregistered}, \cs{\textcircled}, and \cs{\copyright}, % as well as for all registered fonts and accents. Instead of putting \cs{\noexpand} % manually in front of such commands, as in |\def\foo{foo {\noexpand\bar} bar}| |\so\foo|, % you can also register them as special (see section \ref{sec:soulregister}). % \item[Other weird stuff: \so{foo \verb|\bar| baz}] % \soul\ arguments must not contain \LaTeX\ environments, command definitions, % and fancy stuff like |\vadjust|. \soul's |\footnote| command replacement % does not support optional arguments. As long as you are writing simple, % ordinary `horizontal' material, you are on the safe side. % \end{verblist} % % % % % % % % \begin{table} % \begin{center} % \catcode`\|=12 % \newcommand*\pref[1]{{\footnotesize\pageref{cmd:#1}}} % \newcommand*\Ast{\rlap{$^\ast$}} % \let\m\cs % \let\ti\textit % \begin{tabular}{r@{\hspace{.6em}}c@{\hspace{.6em}}l} % &\hbox to0pt{\hss\footnotesize page\hss}&\\[.5ex] % \verb+\so{letterspacing}+& \pref{so} &\so{letterspacing}\\ % \verb+\caps{CAPITALS, Small Capitals}+& \pref{caps} &\caps{CAPITALS, Small Capitals}\\ % \verb+\ul{underlining}+& \pref{ul} &\ul{underlining}\\ % \verb+\st{striking out}+& \pref{st} &\st{striking out}\\ % \verb+\hl{highlighting}+& \pref{hl} &highlighting\\ % \\ % \verb+\soulaccent{\cs}+& \pref{soulaccent} &\ti{add accent} \cs{\cs} \ti{to accent list}\\ % \verb+\soulregister{\cs}{0}+& \pref{soulregister} &\ti{register command} \m{\cs}\\ % \verb+\sloppyword{text}+& \pref{sloppyword} &\ti{typeset} \m{text} \ti{with stretchable spaces}\\ % \\ % \verb+\sodef\cs{1em}{2em}{3em}+& \pref{sodef} &\ti{define new spacing command} \m{\cs}\\ % \verb+\resetso+& \pref{resetso} &\ti{reset} \m{\so} \ti{dimensions}\\ % \verb+\capsdef{////}{1em}{2em}{3em}+\Ast& \pref{capsdef} &\ti{define (default)} \m{\caps} \ti{data entry}\\ % \verb+\capssave{name}+\Ast& \pref{capssave} &\ti{save} \m{\caps} \ti{database under name} \rlap{\texttt{name}}\\ % \verb+\capsselect{name}+\Ast& \pref{capssave} &\ti{restore} \m{\caps} \ti{database of name} \rlap{\texttt{name}}\\ % \verb+\capsreset+\Ast& \pref{capsreset} &\ti{clear caps database}\\ % \verb+\setul{1ex}{2ex}+& \pref{setul} &\ti{set} \m{\ul} \ti{dimensions}\\ % \verb+\resetul+& \pref{resetul} &\ti{reset} \m{\ul} \ti{dimensions}\\ % \verb+\setuldepth{y}+& \pref{setuldepth} &\ti{set underline depth to depth of an} y\\ % \verb+\setuloverlap{1pt}+& \pref{setuloverlap} &\ti{set underline overlap width}\\ % \verb+\setulcolor{red}+& \pref{setulcolor} &\ti{set underline color}\\ % \verb+\setstcolor{green}+& \pref{setstcolor} &\ti{set overstriking color}\\ % \verb+\sethlcolor{blue}+& \pref{sethlcolor} &\ti{set highlighting color}\\ % \end{tabular} % \caption{List of all available commands. The number points to the % page where the command is described. Those marked % with a little asterisk are only available when the package % is used together with \LaTeX, because they rely on the % \emph{New Font Selection Scheme (NFSS)} used in \LaTeX.} % \label{tab:survey} % \end{center} % \end{table} % % % % % % % % \subsection{Troubleshooting} % % Unfortunately, there's just one helpful error message provided by % the \soul\ package, that actually describes the underlying problem. All other % messages are generated directly by \TeX\ and show the low-level % commands that \TeX\ wasn't happy with. They'll hardly point you % to the violated rule as described in the paragraphs above. % If you get such a mysterious error message for a line that contains % a \soul\ statement, then comment that statement out and see if the message % still appears. % \texttt{`Incomplete }\cs{\ifcat}\texttt{'} is such a non-obvious message. % If the message doesn't appear now, then check the argument for % violations of the rules as listed in~\S\S\,20--26. % % % % \subsubsection{\texttt{`Reconstruction failed'}} % % This message appears, if \ref{par:Grouping hyphenatable material} or % \ref{par:Leaking font switches} was % violated. It is caused by the fact that the reconstruction pass % couldn't collect tokens with an overall width of the syllable that % was measured by the analyzer. This does either occur when you % grouped hyphenatable text or used an unregistered command % that influences the syllable width. Font switching commands belong % to the latter group. See the above cited sections for how to fix % these problems. % % % % \subsubsection{Missing characters} % % If you have redefined the internal font as described in section \ref{sec:internalfont}, % you may notice that some characters are omitted without any error message % being shown. This happens if you have chosen, let's say, a font with % only 128~characters like the |cmtt10| font, but are using characters % that aren't represented in this font, e.\,g.~characters with codes % greater than~127. % % % % % % % % % % \section{\so{Letterspacing}} % % \subsection{How it works} % \label{sec:so} % % The base macro for letterspacing is called \describemacro{\so}. % It typesets the given argument with \syn{inter-letter space} % between every two characters, \syn{inner space} between words % and \syn{outer space} before and after the spaced out text. % If we let ``$\cdot$'' stand for \syn{inter-letter space}, ``$\ast$'' % for \syn{inner spaces} and ``$\bullet$'' for \syn{outer % spaces,} then the input on the left side of the following table % will yield the schematic output on the right side: % % \begin{center} % \def\.{$\cdot$} % \def\-{\kern1pt$\ast$\kern1pt} % \def\*{$\bullet$} % \def\_{\texttt{\char"20}} % \begin{tabular}{ccc} % 1.& \verb*|XX\so{aaa bbb ccc}YY|& \textsf{XXa\.a\.a\-b\.b\.b\-c\.c\.cYY}\\ % 2.& \verb*|XX \so{aaa bbb ccc} YY|& \textsf{XX\*a\.a\.a\-b\.b\.b\-c\.c\.c\*\kern-1ptYY}\\ % 3.& \verb*|XX {\so{aaa bbb ccc}} YY|& \textsf{XX\*a\.a\.a\-b\.b\.b\-c\.c\.c\*\kern-1ptYY}\\ % 4.& \verb*|XX \null{\so{aaa bbb ccc}}{} YY|& \textsf{XX\_a\.a\.a\-b\.b\.b\-c\.c\.c\_YY}\\ % \end{tabular} % \end{center} % ^^A* % fool vim (fixes syntax highlighting) % % \noindent % Case~1 shows how letterspacing macros (\cs{\so} and \cs{\caps}) behave if % they aren't following or followed by a space: they omit outer space around % the \soul\ statement. Case~2 is what you'll mostly need---letterspaced % text amidst running text. Following and leading space get replaced by % \syn{outer space}. It doesn't matter if there are opening braces before % or closing braces afterwards. \soul\ can see through both of them (case~3). % Note that leading space has to be at least |5sp| wide to be recognized as % space, because \LaTeX\ uses tiny spaces generated by |\hskip1sp| as marker. % Case~4 shows how to enforce normal spaces instead of \syn{outer spaces:} % Preceding space can be hidden by |\kern0pt| or \cs{\null} or any character. % Following space can also be hidden by any token, but note that a typical macro name % like \cs{\relax} or \cs{\null} would also hide the space thereafter. % % % The values are predefined for typesetting facsimiles mainly with % \emph{Fraktur} fonts. % You can define your own spacing % macros or overwrite the original \cs{\so} meaning using the macro % \describemacro{\sodef}: % % \begin{syntax} % |\sodef|\|{|\|}{|\|}{|\|}{|\|}| % \end{syntax} % % The space dimensions, all of which are mandatory, should be defined in terms of |em| % letting them grow and shrink with the respective fonts. % % \begin{example} % |\sodef\an{}{.4em}{1em plus1em}{2em plus.1em minus.1em}| % \end{example} % % After that you can type `|\an{example}|' to get % {\sodef\an{}{.4em}{1em plus1em}{2em plus.1em minus.1em}^^A % `\an{example}'.} % The \describemacro{\resetso} command resets \cs{\so} % to the default values. % % % % % \subsection{Some examples} % %^^A===================================================== % \begin{examples} % % \soultest{Ordinary text} % |\so{electrical industry}| % {\so{electrical industry}} % % \soultest{Use \texttt{\string\-} to mark hyphenation points} % |\so{man\-u\-script}| % {\so{man\-u\-script}} % % \soultest{Accents are recognized} % |\so{le th\'e\^atre}| % {\so{le th\'e\^atre}} % % \soultest{\texttt{\string\mbox} and \texttt{\string\hbox} protect material that % contains hyphenation points. The contents are treated as one, unbreakable entity} % |\so{just an \mbox{example}}| % {\so{just an \mbox{example}}} % % \soultest{Punctuation marks are spaced out, if they are % put into the group} % |\so{inside.} \& \so{outside}.| % {\so{inside.} \& \so{outside}.} % % \soultest{Space-out skips may be removed by typing \texttt{\string\<}. % It's, however, desirable to put the quotation marks out of % the argument} % |\so{``\|}{|\|}| % \end{syntax} % % Either dimension can be omitted, in which case there has to be % an empty pair of braces. % Both values should be defined in terms of |ex|, letting them % grow and shrink with the respective fonts. % The \describemacro{\resetul} command restores the standard values. % % Another way to set the \syn{underline depth} is to use the macro % \describemacro{\setuldepth}. It sets the depth such that the % underline's upper edge lies 1\,pt beneath the given argument's % deepest depth. If the argument is empty, all % letters---i.\,e.\ all characters whose \cs{\catcode} currently % equals 11---are taken. Examples: % % \begin{example} % |\setuldepth{ygp}|\\ % |\setuldepth\strut|\\ % |\setuldepth{}|\\ % \end{example} % % % % \subsubsection{Line color} % % The underlines are by default black. The color can be changed by % using the \describemacro{\setulcolor} command. It takes one argument that can be any % of the color specifiers as described in the |color| package. This package % has to be loaded explicitly. % % \indent % \begin{example} % |\documentclass{article}|\\ % |\usepackage{color,soul}|\\ % |\definecolor{darkblue}{rgb}{0,0,0.5}|\\ % |\setulcolor{darkblue}|\\ % \end{example} % % \indent % \begin{example} % |\begin{document}|\\ % |...|\\ % |\ul{Cave: remove all the underlines!}|\\ % |...|\\ % |\end{document}|\\ % \end{example} % % % The colors for overstriking lines and highlighting are likewise set % with \describemacro{\setstcolor} (default: black) and \describemacro{\sethlcolor} % (default: yellow). If the \package{color} package wasn't loaded, % underlining and overstriking color are black, while highlighting % is replaced by underlining. % % % % % % % % \subsubsection{The \program{dvips} problem} % \label{sec:dvips} % % \ul{Underlining}, \st{striking out} and highlighting build up % their lines with many short line segments. If you used the `\program{dvips}' % program with default settings, you would get little gaps on some places, because % the \emph{maxdrift} parameter allows the single objects to drift % this many pixels from their real positions. % \bigbreak % % \noindent % There are two ways to avoid the problem, where the \soul\ package % chooses the second by default: % \begin{enumerate} % \item % Set the \emph{maxdrift} value to zero, e.\,g.: |dvips -e 0 file.dvi|. % This is probably not a good idea, since the letters may then no longer be % spaced equally on low resolution printers. % \item % Let the lines stick out by a certain amount on each side so that they % overlap. This overlap amount can be set using the \describemacro{\setuloverlap} % command. It is set to 0.25\,pt by default. |\setuloverlap{0pt}| turns overlapping off. % \end{enumerate} % % % % % % % \subsection{Some examples} % %^^A===================================================== % \begin{examples} % % \soultest{Ordinary text} % |\ul{electrical industry}| % {\ul{electrical industry}} % % \soultest{Use \texttt{\string\-} to mark hyphenation points} % |\ul{man\-u\-script}| % {\ul{man\-u\-script}} % % \soultest{Accents are recognized} % |\ul{le th\'e\^atre}| % {\ul{le th\'e\^atre}} % % \soultest{\texttt{\string\mbox} and \texttt{\string\hbox} protect material that % contains hyphenation points. The contents are treated as one, unbreakable entity} % |\ul{just an \mbox{example}}| % {\ul{just an \mbox{example}}} % % \soultest{Explicit hyphens like |-|, |--| and |---| are recognized. % \texttt{\string\slash} outputs a slash and enables \TeX\ to break the line % afterwards} % |\ul{input\slash output}| % {\ul{input\slash output}} % % \soultest{To keep \TeX\ from breaking lines between the hyphen and `jet' % you have to protect the hyphen. This is no \soul\ restriction % but normal \TeX\ behavior} % |\ul{\dots and \mbox{-}jet}| % {\ul{\dots and \mbox{-}jet}} % % \soultest{The \texttt{\~} command inhibits line breaks} % |\ul{unbreakable~space}| % {\ul{unbreakable~space}} % % \soultest{\texttt{\string\\} works as usual. Additional arguments % like \texttt{*} or vertical space are not accepted, though} % |\ul{broken\\line}| % {\ul{broken\\line}} % % \soultest{\texttt{\string\break} breaks the line without filling it with white space} % |\ul{pretty awful\break test}| % {\ul{pretty awful\break test}} % % \soultest{Italic correction needs to be set manually} % |\ul{foo \emph{bar\/} baz}| % {\ul{foo \emph{bar\/} baz}} % % \end{examples} %^^A===================================================== % % % % % % % % % % % % % % \section{Customization} % % \subsection{Adding accents} % \label{sec:soulaccent} % % The \soul\ scanner generally sees every input token separately. % It has to be taught that some tokens belong together. For accents this is done % by registering them via the \describemacro{\soulaccent} macro. % % \begin{syntax} % |\soulaccent{|\|}| % \end{syntax} % % The standard accents, however, are already pre-registered: % |\`|, |\'|, |\^|, |\"|, |\~|, |\=|, |\.|, |\u|, |\v|, |\H|, |\t|, % |\c|, |\d|, |\b|, and |\r|. If used together with the \package{german} % package, \soul\ automatically adds the |"| command. % Let's assume you have defined |\%| to put some weird accent on % the next character. Simply put the following line into your |soul.cfg| % file (see section~\ref{sec:config}): % % \begin{example} % |\soulaccent{\%}| % \end{example} % % Note that active characters like the |"| command have already % to be \cs{\active} when they are stored or they won't be recognized % later. This can be done temporarily, as in |{\catcode\`"\active\soulaccent{"}}|. % % % % % \subsection{Adding font commands} % \label{sec:soulregister} % % To convince \soul\ not to feed font switching (or other) % commands to the analyzer, but rather to execute them immediately, % they have to be registered, too. The \describemacro{\soulregister} macro % takes the name of a command name and either |0| or |1| for the number % of arguments: % % \begin{syntax} % |\soulregister{|\|}{|\|}| % \end{syntax} % % If \cs{\bf} and \cs{\emph} weren't already registered, you would % write the following into your |soul.cfg| configuration file: % % \begin{example} % |\soulregister{\bf}{0} % {\bf foo}| \\ % |\soulregister{\emph}{1} % \emph{bar}|\\ % \end{example} % % % All standard \TeX\ and \LaTeX\ font commands, as well as the % \package{yfonts} commands are already pre-registered: % % \begin{example} % |\em, \rm, \bf, \it, \tt, \sc, \sl, \sf, \emph, \textrm,|\\ % |\textsf, \texttt, \textmd, \textbf, \textup, \textsl,|\\ % |\textit, \textsc, \textnormal, \rmfamily, \sffamily,|\\ % |\ttfamily, \mdseries, \upshape, \slshape, \itshape,|\\ % |\scshape, \normalfont, \tiny, \scriptsize, \footnotesize,|\\ % |\small, \normalsize, \large, \Large, \LARGE, \huge, \Huge,|\\ % |\MakeUppercase, \textsuperscript, \footnote,|\\ % |\textfrak, \textswab, \textgoth, \frakfamily,|\\ % |\swabfamily, \gothfamily|\\ % \end{example} % % You can also register other commands as fonts, so the % analyzer won't see them. This may be necessary for some % macros that \soul\ refuses to typeset correctly. % But note, that \cs{\so} and \cs{\caps} won't put their % letter-skips around then. % % % % % % % \subsection{Changing the internal font} % \label{sec:internalfont} % % The \soul\ package uses the |ectt1000| font while it analyzes % the syllables. This font is used, because it % has 256~mono-spaced characters without any kerning. % It belongs to \person{J\"org Knappen'\textrm{s}} % \caps{EC}-fonts, which should be part of every modern \TeX\ installation. % If \TeX\ reports ``\texttt{I can't find file `ectt1000'}'' you don't % seem to have this font installed. It is recommended that % you install at least the file |ectt1000.tfm| which has less than 1.4\,kB\null. % Alternatively, you can let the \soul\ package use the |cmtt10| font that % is part of any installation, or some other mono-spaced font: % % \begin{example} % |\font\SOUL@tt=cmtt10| % \end{example} % % Note, however, that \soul\ does only handle characters, % for which the internal font has a character with the same % character code. As |cmtt10| contains only characters with codes % 0 to~127, you can't typeset characters with codes 128 to~255. % These 8-bit character codes are used by many fonts with non-ascii % glyphs. So the |cmtt10| font will, for example, not work for |T2A| % encoded cyrillic characters. % % % % % % % % \subsection{The configuration file} % \label{sec:config} % % If you want to change the predefined settings or add new features, % then create a file named `|soul.cfg|' and put it in a directory, where \TeX\ % can find it. This configuration file will then be loaded % at the end of the |soul.sty| file, so you may redefine % any settings or commands therein, select package options and even % introduce new ones. But if you intend to give % your documents to others, don't forget to give them the % required configuration files, too! That's how such a file % could look like: % % \indent % \begin{example} % |% define macros for logical markup|\\ % |\sodef\person{\scshape}{0.125em}{0.4583em}{0.5833em}|\\ % \\ % |\sodef\SOUL@@@versal{\upshape}{0.125em}{0.4583em}{0.5833em}|\\ % |\DeclareRobustCommand*\versal[1]{%|\\ % | \MakeUppercase{\SOUL@@@versal{#1}}%|\\ % |}|\\ % \end{example} % % \indent % \begin{example} % |% load the color package and set|\\ % |% a different highlighting color|\\ % |\RequirePackage{color}|\\ % |\definecolor{lightblue}{rgb}{.90,.95,1}|\\ % |\sethlcolor{lightblue}|\\ % |\endinput| % \end{example} % % You can safely use the |\SOUL@@@| namespace for internal macros---it % won't be used by the \soul\ package in the future. % % % % % % % % % % % \section{Miscellaneous} % % \subsection{Using \soul\ with other flavors of \TeX} % \label{sec:plain} % % This documentation describes how to use \soul\ together % with \LaTeXe, for which it is optimized. It works, however, with % all other flavors of \TeX, too. There are just some minor restrictions % for Non-\LaTeX\ use: % % The \cs{\caps} command doesn't use a database, it is only a dumb % definition with fixed values. It switches to \cs{\capsfont}, which---unless % defined explicitly like in the following example---won't really change % the used font at all. The commands \cs{\capsreset} and \cs{\capssave} % do nothing. % % \begin{example} % |\font\capsfont=cmcsc10|\\ % |\caps{Tschichold}|\\ % \end{example} % % None of the commands are made `robust', so they have to be % explicitly protected in fragile environments like in \cs{\write} % statements. % To make use of colored underlines or highlighting you have to % use the \package{color} package wrapper from \caps{CTAN}^^A % \footnote{\texttt{CTAN:/macros/plain/graphics/\char`\{miniltx.tex,color.tex\char`\}}}, % instead of the \package{color} package directly: % % \begin{example} % |\input color|\\ % |\input soul.sty|\\ % |\hl{highlighted}|\\ % |\bye|\\ % \end{example} % % The \option{capsdefault} package option is mapped to a simple command % \describemacro{\capsdefault}. % % % % % % % % \subsection{Using \soul\ commands for logical markup} % \label{sec:markup} % % It's generally a bad idea to use font style commands like \cs{\textsc} % in running text. There should always be some reasoning behind changing % the style, such as ``names of persons shall be typeset in a caps-and-small-caps % font''. So you declare in your text just that some words are the name of a % person, while you define in the preamble or, even better, in a separate % style file how to deal with persons: % % \begin{example} % |\newcommand*\person{\textsc}|\\ % |...|\\ % |``I think it's a beautiful day to go to the zoo and feed|\\ % |the ducks. To the lions.'' --~\person{Brian Kantor}|\\ % \end{example} % % It's quite simple to use \soul\ commands that way: % % \begin{example} % |\newcommand\comment*{\ul} % or \let\comment=\ul|\\ % |\sodef\person{\scshape}{0.125em}{0.4583em}{0.5833em}|\\ % \end{example} % % Letterspacing commands like \cs{\so} and \cs{\caps} have to % check whether they are followed by white space, in which case % they replace that space by \syn{outer space}. Note that \soul\ % does look through closing braces. Hence you can conveniently bury % a \soul\ command within another macro like in the following % example. Use any other token to hide following space if necessary, % for example the \cs{\null} macro. % % \begin{example} % |\DeclareRobustCommand*\versal[1]{%|\\ % | \MakeUppercase{\SOUL@@@versal{#1}}%|\\ % |}|\\ % |\sodef\SOUL@@@versal{\upshape}{0.125em}{0.4583em}{0.5833em}|\\ % \end{example} % % % But what if the \soul\ command is for some reason not the last one % in that macro definition and thus cannot look ahead at the following token? % % % \begin{example} % |\newcommand*\somsg[1]{\so{#1}\message{#1}}|\\ % |...|\\ % |foo \somsg{bar} baz % wrong spacing after `bar'!|\\ % \end{example} % % In this case you won't get the following space replaced by \emph{outer space} % because when \soul\ tries to look ahead, it only sees the token % \cs{\message} and consequently decides that there is no space to replace. % You can get around this by explicitly calling the space scanner again. % % \begin{example} % |\newcommand*\somsg[1]{{%|\\ % | \so{#1}%|\\ % | \message{bar}%|\\ % | \let\\\SOUL@socheck|\\ % | \\%|\\ % |}}|\\ % \end{example} % % However, \cs{\SOUL@socheck} can't be used directly, because it would discard % any normal space. \cs{\\} doesn't have this problem. % The additional pair of braces avoids that its definition leaks out % of this macro. In the example above you could, of course, simply % have put \cs{\message} in front, so you hadn't needed to % use the scanner macro \cs{\SOUL@socheck} at all. % % Many packages do already offer logical markup commands that default % to some standard \LaTeX\ font commands or to \cs{\relax}. One example % is the \package{jurabib} package~\cite{jurabib}, which makes the use of % \soul\ a challenge. This package implements lots of % formatting macros. Let's have a look at one of them, \cs{\jbauthorfont}, % which is used to typeset author names in citations. % The attempt to simply % define |\let\jbauthorfont\caps| fails, because the macro isn't directly % applied to the author name as in |\jbauthorfont{Don Knuth}|, but % to another command sequence: |\jbauthorfont{\jb@@author}|. Not even % \cs{\jb@@author} contains the name, but instead further commands that % at last yield the requested name. That's why we have to expand % the contents first. This is quite tricky, because we must not % expand too much, either. Fortunately, we can offer the contents % wrapped up in yet another macro, so that \soul\ knows that it has to % use its own macro expansion mechanism: % % \begin{example} % |\renewcommand*\jbauthorfont[1]{{%|\\ % | \def\x{#1}%|\\ % | \caps\x|\\ % |}}|\\ % \end{example} % % Some additional kerning after |\caps\x| wouldn't hurt, because % the look-ahead scanner is blinded by further commands that follow % in the \package{jurabib} package. Now we run into the next problem: % cited names may contain commands % that must not get expanded. We have to register them as special % command: % % \begin{example} % |\soulregister\jbbtasep{0}|\\ % |...|\\ % \end{example} % % But such registered commands bypass \soul's kernel and we don't % get the correct spacing before and afterwards. So we end up % redefining \cs{\jbbtasep}, whereby you should, of course, use % variables instead of numbers: % % \begin{example} % |\renewcommand*\jbbtasep{%|\\ % | \kern.06em|\\ % | \slash|\\ % | \hskip.06em|\\ % | \allowbreak|\\ % |}|\\ % \end{example} % % Another problem arises: bibliography entries that must not get % teared apart are supposed to be enclosed in additional braces. % This, however, won't work with \soul\ because of % \ref{par:Grouping hyphenatable material}. A simple trick will % get you around that problem: define a dummy command that only % outputs its argument, and register that command: % % \begin{example} % |\newcommand*\together[1]{#1}|\\ % |\soulregister\together{1}|\\ % \end{example} % % Now you can write ``|Author = {\together{Don Knuth}}|'' and % \package{jurabib} won't dare to reorder the parts of the name. % And what if some name shouldn't get letterspaced at all? Overriding % a conventional font style like \cs{\textbf} that was globally % set is trivial, you just have to specify the style that you % prefer in that very bibliography entry. In our example, if we % wanted to keep \soul\ from letterspacing a particular entry, % although they are all formatted by our \cs{\jbauthorfont} % and hence fed to \cs{\caps}, we'd use the following construction: % % \begin{example} % |Author = {\soulomit{\normalfont\huge Donald E. Knuth}}|\\ % \end{example} % % The \package{jurabib} package is probably one of the more % demanding packages to collaborate with \soul. Everything else % can just become easier. % % % % % % % % % \subsection{Typesetting long words in narrow columns} % \label{sec:sloppyword} % % Narrow columns are best set |flushleft|, because not even the best % hyphenation algorithm can guarantee acceptable line breaks without % overly stretched spaces. % However, in some rare cases one may be \emph{forced} to typeset % block aligned. When typesetting in languages like German, where % there are really long words, the \describemacro{\sloppyword} macro % might help a little bit. It adds enough stretchability between the % single characters to make the hyphenation algorithm happy, but % is still not as ugly as the example in section~\ref{sec:dirtytricks} % demonstrates. In the following example the left column was typeset % as ``|Die \sloppyword{Donau...novelle} wird ...|'': % % \begin{center} % \def\word{Do\-nau\-dampf\-schiff\-fahrts\-ge\-sell\-schafts\-^^A % ka\-pi\-t\"ans\-wit\-wen\-pen\-si\-ons\-ge\-setz\-no\-vel\-le} % \begin{minipage}{1.5in} % \plainsetup % Die % \expandafter\sloppyword\expandafter{\word} % wird mit sofortiger Wirkung au\ss er Kraft gesetzt. % \end{minipage} % \hspace{1em} % \batchmode % \begin{minipage}{1.5in} % \plainsetup % Die \word\ wird mit sofortiger Wirkung au\ss er Kraft gesetzt. % \end{minipage} % \errorstopmode % \end{center} % % % % % % % % \subsection{Using \soul\ commands in section headings} % % Letterspacing was often used for section titles in the past, % mostly centered and with a closing period. The following example % shows how to achieve this using the \package{titlesec} % package \cite{titlesec}: % % \begin{example} % |\newcommand*\periodafter[2]{#1{#2}.}|\\ % |\titleformat{\section}[block]|\\ % | {\normalfont\centering}|\\ % | {\thesection.}|\\ % | {.66em}|\\ % | {\periodafter\so}|\\ % |...|\\ % |\section{Von den Maassen und Maassst\"aben}|\\ % \end{example} % % \bigbreak % This yields the following output: % % \bigskip % \newbox\examplebox % \sbox\examplebox{ % \begin{minipage}{.9\textwidth} % \small % \bigskip % \begin{center} % \so{1\<. Von den Maassen und Maassst\"aben}. % \bigskip % \end{center} % \end{minipage}} % \fbox{\usebox\examplebox} % \bigbreak % % \noindent % The \cs{\periodafter} macro adds a period to the title, but not to % the entry in the table of contents. It takes the name of a command as % argument, that shall be applied to the title, for example~\cs{\so}. % Here's a more complicated and complete example: % % \begin{example} % |\documentclass{article}|\\ % |\usepackage[latin1]{inputenc}|\\ % |\usepackage[T1]{fontenc}|\\ % |\usepackage{german,soul}|\\ % |\usepackage[indentfirst]{titlesec}|\\ % \end{example} % % \indent % \begin{example} % |\newcommand*\sectitle[1]{%|\\ % | \MakeUppercase{\so{#1}.}\\[.66ex]|\\ % | \rule{13mm}{.4pt}}|\\ % |\newcommand*\periodafter[2]{#1{#2.}}|\\ % \end{example} % % \indent % \begin{example} % |\titleformat{\section}[display]|\\ % | {\normalfont\centering}|\\ % | {\S. \thesection.}|\\ % | {2ex}|\\ % | {\sectitle}|\\ % \end{example} % % \indent % \begin{example} % |\titleformat{\subsection}[block]|\\ % | {\normalfont\centering\bfseries}|\\ % | {\thesection.}|\\ % | {.66em}|\\ % | {\periodafter\relax}|\\ % \end{example} % % \indent % \begin{example} % |\begin{document}|\\ % |\section{Von den Maassen und Maassst\"aben}|\\ % |\subsection{Das L\"angenmaass im Allgemeinen}|\\ % \\ % |Um L\"angen genau messen und vergleichen zu k\"onnen,|\\ % |bedarf es einer gewissen, bestimmten Einheit, mit der|\\ % |man untersucht, wie oft sie selbst, oder ihre Theile,|\\ % |in der zu bestimmenden L\"ange enthalten sind.|\\ % |...|\\ % |\end{document}| % \end{example} % % \bigbreak % This example gives you roughly the following output, % which is a facsimile from~\cite{Muszynski}. % % \bigskip % \sbox\examplebox{ % \begin{minipage}{.9\textwidth} % \small % \bigskip % \begin{center} % \S. 1.\\[2ex] % \so{VON DEN MAASSEN UND MAASSST\"ABEN}.\\[.66ex] % \rule{12mm}{.4pt}\\[1.66ex] % \textbf{1. Das L\"angenmaass im Allgemeinen.}\\[.66em] % \end{center} % \leavevmode\qquad % Um L\"angen genau messen und vergleichen zu k\"onnen, % bedarf es einer gewissen, bestimmten Einheit, mit der % man untersucht, wie oft sie selbst, oder ihre Theile, % in der zu bestimmenden L\"ange enthalten sind. % \bigskip % \end{minipage}} % \fbox{\usebox\examplebox} % \bigbreak % % \noindent % Note that the definition of \cs{\periodafter} decides if % the closing period shall be spaced out with the title (1), or % follow without space (2): % % \begin{example} % 1.\qquad|\newcommand*\periodafter[2]{#1{#2.}}|\\ % 2.\qquad|\newcommand*\periodafter[2]{#1{#2}.}|\\ % \end{example} % % % % \noindent % If you need to underline section titles, you can easily % do it with the help of the \package{titlesec} package. The following % example underlines the section title, but not the section % number: % % \begin{example} % |\titleformat{\section}|\\ % | {\LARGE\titlefont}|\\ % | {\thesection}|\\ % | {.66em}|\\ % | {\ul}|\\ % \end{example} % % \noindent % The \cs{\titlefont} command is provided by the \caps{``\small{KOMA}}~script'' % package. You can write |\normalfont\sffamily\bfseries| instead. % The following example does additionally underline the section number: % % \begin{example} % |\titleformat{\section}|\\ % | {\LARGE\titlefont}|\\ % | {\ul{\thesection{\kern.66em}}}|\\ % | {0pt}|\\ % | {\ul}|\\ % \end{example} % % % % % % % % % % % % \section{How the package works} % % \subsection{The kernel} % \so{Letterspacing,} \ul{underlining}, \st{striking out} and highlighting % use the same kernel. It lets a \emph{word scanner} run over the given argument, % which inspects every token. If a token is a command registered via \cs{\soulregister}, % it is executed immediately. Other tokens are only counted and trigger some action % when a certain number is reached (quotes and dashes). Three subsequent `|-|', for example, % trigger |\SOUL@everyexhyphen{---}|. A third group leads to special actions, % like |\mbox| that starts reading-in a whole group to protect its contents and let them be % seen as one entity. All other tokens, mostly characters and digits, are collected in % a word register, which is passed to the analyzer, whenever a whole word was read in. % % The analyzer typesets the word in a 1\,sp ($=\frac1{65536}$\,pt) wide \cs{\vbox}, % hence encouraging \TeX\ to break lines at every possible hyphenation point. It % uses the mono-spaced \cs{\SOUL@tt} font (|ectt1000|), so as to avoid any inter-character % kerning. Now the \cs{\vbox} is decomposed splitting off \cs{\hbox} after \cs{\hbox} % from the bottom. All boxes, each of which contains one syllable, are pushed onto a % stack, which is provided by \TeX's grouping mechanism. When returning from the % recursion, box after box is fetched from the stack, its width measured and fed to the %``reconstructor''. % % This reconstruction macro (\cs{\SOUL@dosyllable}) starts to read tokens % from the just analyzed word until the given syllable % width is obtained. This is repeated for each syllable. Every time the engine % reaches a relevant state, the corresponding driver macro is executed % and, if necessary, provided with some data. There is a macro that is % executed for each token, one for each syllable, one for each space etc\null. % % The engine itself doesn't know how to letterspace or to underline. It % just tells the selected driver about the structure of the given argument. % There's a default driver (\cs{\SOUL@setup}) that does only set the % interface macros to a reasonable default state, but doesn't really do anything. % Further drivers can safely inherit these settings and only need to % redefine what they want to change. % % % % % % \subsection{The interface} % \label{sec:interface} % % \subsubsection{The registers} % % The package offers eight interface macros that can be used to define % the required actions. Some of the macros receive data as macro parameter % or in special \emph{token} or \emph{dimen} registers. Here is a list of % all available registers: % % \begin{labeling}{\hspace{.36\hsize}} % \item[\texttt{\string\SOUL@token}] % This token register contains the current token. It has to be used as |\the\SOUL@token|. % The macro \cs{\SOUL@gettoken} reads the next token into \cs{\SOUL@token} and % can be used in any interface macro. If you don't want to lose the old meaning, % you have to save it explicitly. \cs{\SOUL@puttoken} pushes the token % back into the queue, without changing \cs{\SOUL@token}. You can only % put one token back, otherwise you get an error message. % \item[\texttt{\string\SOUL@lasttoken}] % This token register contains the last token. % \item[\texttt{\string\SOUL@syllable}] % This token register contains all tokens that were already collected for % the current syllable. When used in \cs{\SOUL@everysyllable}, it % contains the \emph{whole} syllable. % \item[\texttt{\string\SOUL@charkern}] % This dimen register contains the kerning value between the current and the next character. % Since most character pairs don't require a kerning value to be applied and the % output in the logfile shouldn't be cluttered with |\kern0pt| it is % recommended to write |\SOUL@setkern\SOUL@charkern|, which sets % kerning for non-zero values only. % \item[\texttt{\string\SOUL@hyphkern}] % This dimen register contains the kerning value between the current character % and the hyphen character or, when used in \cs{\SOUL@everyexhyphen}, the % kerning between the last character and the explicit hyphen. % \end{labeling} % % % % % % % \subsubsection{The interface macros} % % The following list describes each of the interface macros and which % registers it can rely on. The mark between label and description % will be used in section \ref{sec:interfaceexamples} to show when % the macros are executed. The addition |#1| means that the macro % takes one argument. % % \begin{labeling}{\hspace{.36\hsize}} % \def\m#1{\leavevmode\llap{\hbox to1em{\hss#1\hss}\hskip.7em}} % \item[\texttt{\string\SOUL@preamble}]\m{$P$}^^A % executed once at the beginning % \item[\texttt{\string\SOUL@postamble}]\m{$E$}^^A % executed once at the end % \item[\texttt{\string\SOUL@everytoken}]\m{$T$}^^A % executed after scanning a token; It gets that % token in \cs{\SOUL@token} and has to care for inserting % the kerning value \cs{\SOUL@charkern} between this and the next character. % To look at the next character, execute \cs{\SOUL@gettoken}, which % replaces \cs{\SOUL@token} by the next token. This token has to % be put back into the queue using \cs{\SOUL@puttoken}. % \item[\texttt{\string\SOUL@everysyllable}]\m{$S$}^^A % This macro is executed after scanning a whole syllable. It gets the % syllable in \cs{\SOUL@syllable}. % \item[\texttt{\string\SOUL@everyhyphen}]\m{$-$}^^A % This macro is executed at every implicit hyphenation point. % It is responsible for setting the hyphen and will likely do this % in a \cs{\discretionary} statement. It has to care about the % kerning values. The registers \cs{\SOUL@lasttoken}, \cs{\SOUL@syllable}, % \cs{\SOUL@charkern} and \cs{\SOUL@hyphkern} contain useful information. % Note that \cs{\discretionary} inserts \cs{\exhyphenpenalty} % if the first part of the discretionary is empty, and % \cs{\hyphenpenalty} else. % \item[\texttt{\string\SOUL@everyexhyphen\#1}]\m{$=$}^^A % This macro is executed at every explicit hyphenation point. The % hyphen `character' (one of hyphen, en-dash, em-dash or \cs{\slash}) % is passed as parameter |#1|. A minimal implementation % would be |{#1\penalty\exhyphenpenalty}|. The kerning value % between the last character and the hyphen is passed in \cs{\SOUL@hyphkern}, % that between the hyphen and the next character in \cs{\SOUL@charkern}. % The last syllable can be found in \cs{\SOUL@syllable}, the last % character in \cs{\SOUL@lasttoken}. % \item[\texttt{\string\SOUL@everyspace\#1}]\m{\texttt{\char`\ }}^^A % This macro is executed between every two words. It is responsible for % setting the space. The engine submits a \cs{\penalty} setting as % parameter |#1| that should be put in front of the space. The % macro should at least do |{#1\space}|. Further information can be found in % \cs{\SOUL@lasttoken} and \cs{\SOUL@syllable}. Note that this macro does not % care for the leading and trailing space. This is the job of % \cs{\SOUL@preamble} and \cs{\SOUL@postamble}. % \end{labeling} % % % % % % % \subsubsection{Some examples} % \label{sec:interfaceexamples} % % The above list's middle column shows a mark that indicates in the % following examples, when the respective macros are executed:\nopagebreak % % \begin{labeling}{\hspace{.36\hsize}} % \item[\normalfont\an{word}] % \cs{\SOUL@everytoken}$^T$ is executed for every token. \cs{\SOUL@everysyllable}$^S$ % is \emph{additionally} executed for every syllable. You will mostly just % want to use either of them. % \item[\normalfont\an{one two}] % The macro |\SOUL@everyspace| is executed at every space within % the \soul\ argument. It has to take one argument, that can either % be empty or contain a penalty, that should be applied to the space. % \item[\normalfont\an{example}\kern-1em] % The macro |\SOUL@everyhyphen| is executed at every possible % implicit hyphenation point. % \item[\normalfont\an{beta-test}] % Explicit hyphens trigger \cs{\SOUL@everyexhyphen}. % \end{labeling} % % % % \bigbreak % \noindent % It's only natural that these examples, too, % were automatically typeset by the |soul| package % using a special driver: % % \begin{example} % |\DeclareRobustCommand*\an{%|\\ % | \def\SOUL@preamble{$^{^P}$}%|\\ % | \def\SOUL@everyspace##1{##1\texttt{\char`\ }}%|\\ % | \def\SOUL@postamble{$^{^E}$}%|\\ % | \def\SOUL@everyhyphen{$^{^-}$}%|\\ % | \def\SOUL@everyexhyphen##1{##1$^{^=}$}%|\\ % | \def\SOUL@everysyllable{$^{^S}$}%|\\ % | \def\SOUL@everytoken{\the\SOUL@token$^{^T}$}%|\\ % | \def\SOUL@everylowerthan{$^{^L}$}%|\\ % | \SOUL@}|\\ % \end{example} % % % % % % % % % \subsection{A driver example} % % Let's define a \soul\ driver that allows to typeset text % with a \cs{\cdot} at every potential hyphenation point. The name of % the macro shall be \cs{\sy} (for \emph{syllables}). % Since the \soul\ mechanism is highly fragile, we use the \LaTeX\ % command \cs{\DeclareRobustCommand}, so that the \cs{\sy} macro % can be used even in section headings etc. The \cs{\SOUL@setup} % macro sets all interface macros to reasonable default definitions. % This could of course be done manually, too. As we won't % make use of \cs{\SOUL@everytoken} and \cs{\SOUL@postamble} % and both default to \cs{\relax}, anyway, we don't have to % define them here. % % \begin{example} % |\DeclareRobustCommand*\sy{%|\\ % | \SOUL@setup|\\ % \end{example} % % We only set \cs{\lefthyphenmin} and \cs{\righthyphenmin} to zero % at the beginning. All changes are restored automatically, % so there's nothing to do at the end. % % \begin{example} % | \def\SOUL@preamble{\lefthyphenmin=0 \righthyphenmin=0 }%|\\ % \end{example} % % We only want simple spaces. Note that these are not provided % by default! \cs{\SOUL@everyspace} may get a penalty to be % applied to that space, so we set it before. % % \begin{example} % | \def\SOUL@everyspace##1{##1\space}%|\\ % \end{example} % % There's nothing to do for \cs{\SOUL@everytoken}, we rather let % \cs{\SOUL@everysyllable} handle a whole syllable at once. % This has the advantage, that we don't have to deal with % kerning values, because \TeX\ takes care of that. % % \begin{example} % | \def\SOUL@everysyllable{\the\SOUL@syllable}%|\\ % \end{example} % % The \TeX\ primitive \cs{\discretionary} % takes three arguments: 1.~pre-hyphen material % 2.~post-hyphen material, and 3.~no-hyphenation material. % % \begin{example} % | \def\SOUL@everyhyphen{%|\\ % | \discretionary{%|\\ % | \SOUL@setkern\SOUL@hyphkern|\\ % | \SOUL@sethyphenchar|\\ % | }{}{%|\\ % | \hbox{\kern1pt$\cdot$}%|\\ % | }%|\\ % | }%|\\ %\end{example} % % Explicit hyphens like dashes and slashes shall be set normally. % We just have to care for kerning. The hyphen has to be put in % a box, because, as \cs{\hyphenchar}, it would yield its own, internal % \cs{\discretionary}. We need to set ours instead, though. % % \begin{example} % | \def\SOUL@everyexhyphen##1{%|\\ % | \SOUL@setkern\SOUL@hyphkern|\\ % | \hbox{##1}%|\\ % | \discretionary{}{}{%|\\ % | \SOUL@setkern\SOUL@charkern|\\ % | }%|\\ % | }%|\\ % \end{example} % % Now that the interface macros are defined, we can start the scanner. % % \begin{example} % | \SOUL@|\\ % |}|\\ % \end{example} % % \hyphenation{al-go-rithm lin-guists ex-cel-lent} ^^A correct? % \noindent % \emph{\sy{This little macro will hardly be good enough % for linguists, although it uses {\TeX's} excellent hyphenation algorithm, % but it is at least a nice alternative to the}} \cs{\showhyphens} \emph{\sy{command}.} % % % % % % % % \section*{Acknowledgements} % % A big thank you goes to \person{Stefan Ulrich} for his tips and bug reports % during the development of versions 1.\lower2pt\hbox{*} and for his lessons on high quality % typesetting. The \cs{\caps} mechanism was very much influenced by his % suggestions. Thanks to \person{Alexander Shibakov} and \person{Frank Mittelbach,} % who sent me a couple of bug reports and feature requests, and finally encouraged % me to (almost) completely rewrite \soul. \person{Thorsten Manegold} contributed % a series of bug reports, helping to fix \soul's macro expander and hence making % it work together with the \package{jurabib} package. % Thanks to \person{Axel Reichert, Anshuman Pandey,} and \person{Peter Kreynin} for % detailed bug reports. % \person{Rowland McDonnel} gave useful hints for how to improve the documentation, % but I'm afraid he will still not be satisfied, and rightfully so. If only documentation % writing weren't that boring.~~\texttt{;-)} % % % % % % % % \begin{thebibliography}{00} % \raggedright % % \bibitem{jurabib}{\person{Berger, Jens:} \bibtitle{The jurabib package.} \CTAN-Archive, 2002, v0.52h.} % % \bibitem{titlesec}{\person{Bezos, Javier:} \bibtitle{The titlesec and titletoc package.} % \CTAN-Archive, 1999, v2.1.} % % \bibitem{color}{\person{Carlisle, D. P.:} \bibtitle{The color package.} \CTAN-Archive, 1997, v1.0d.} % % \bibitem{Duden}{Duden, Volume 1. \bibtitle{Die Rechtschreibung.} Bibliographisches Institut, % Mann\-heim--\hskip0pt Wien--Z\"urich, 1986, 19th~edition.} % % \bibitem{DEK}{\person{Knuth, Donald E.:} \bibtitle{The \TeX book.} % Addison--Wesley Publishing Company, Reading/Massachusetts, 1989, 16th~edition.} % % \bibitem{Muszynski}{\person{Muszynski, Carl} and \person{P\v rihoda, Eduard:} % \bibtitle{Die Terrainlehre in Verbindung mit der Darstellung, Beurtheilung und % Beschreibung des Terrains vom milit\"arischen % Standpunkte.} % L.\,W.~Seidel \&\ Sohn, Wien, 1872.} % % \bibitem{Reglement}{Normalverordnungsblatt f\"ur das k.\,u.\,k.~Heer. % \bibtitle{Exercier-Reglement f\"ur die k.\,u.\,k.~Cavallerie, I. Theil.} % Wien, k.\,k.~Hof- und Staatsdruckerei, 1898, 4th~edition.} % % \bibitem{german}{\person{Raichle, Bernd:} \bibtitle{The german package.} \CTAN-Archive, 1998, v2.5e.} % % \bibitem{yfonts}{\person{Schmidt, Walter:} \bibtitle{Ein Makropaket f\"ur die gebrochenen % Schriften.} \CTAN-Archive, 1998, v1.2.} % % \bibitem{Tschichold}{\person{Tschichold, Jan:} \bibtitle{Ausgew\"ahlte Aufs\"atze \"uber Fragen % der Gestalt des Buches und der Typographie.} Birkh\"auser, Basel, % 1987, 2nd~edition.} % % \bibitem{Willberg}{\person{Willberg, Hans Peter} and \person{Forssmann, Friedrich:} % \bibtitle{Lesetypographie.} H. Schmidt, Mainz, 1997.} % % \end{thebibliography} % % % \StopEventually{\addtocontents{toc}{\protect\end{multicols}}} % % % % % % % % %^^A max 72 columns %^^A-------------------------------------------------------------------- % % % % % \section{The implementation} % % \subsection*{The package preamble} % % This piece of code makes sure that the package is only loaded % once. While this is guaranteed by \LaTeX, we have to do it % manually for all other flavors of \TeX. % \begin{macrocode} %<*package> % \end{macrocode} % \begin{macrocode} \expandafter\ifx\csname SOUL@\endcsname\relax\else \expandafter\endinput \fi % \end{macrocode} % % % % %^^A-------------------------------------------------------------------- % % % % % \noindent % Fake some of the \LaTeX\ commands if we were loaded by another flavor % of \TeX. This might break some previously loaded packages, though, % if e.\,g.~\cs{\mbox} was already in use. But we don't care \dots % % \begin{macrocode} \ifx\documentclass\SOULundefined \chardef\atcode=\catcode`@ \catcode`\@=11 \def\DeclareRobustCommand*{\def} \let\newcommand\DeclareRobustCommand \def\DeclareOption#1#2{\expandafter\def\csname#1\endcsname{#2}} \def\PackageError#1#2#3{{% \newlinechar`^^J% \errorcontextlines\z@ \edef\\{\errhelp{#3}}\\% \errmessage{Package #1 error: #2}% }} \def\@height{height} \def\@depth{depth} \def\@width{width} \def\@plus{plus} \def\@minus{minus} \font\SOUL@tt=ectt1000 \let\@xobeysp\space \let\linebreak\break \let\mbox\hbox % \end{macrocode} % % % % %^^A-------------------------------------------------------------------- % % % % % \noindent % \soul\ tries to be a good \LaTeX\ citizen if used under \LaTeX\ and % declares itself properly. Most command sequences in the package % are protected by the |SOUL@| namespace, all other macros are first % defined to be empty. This will give us an error message \emph{now} % if one of those was already used by another package. % % \begin{macrocode} \else \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{soul-ori} [2023-06-14 v3.1 letterspacing/underlining (mf)] \newfont\SOUL@tt{ectt1000} \newcommand*\sodef{} \newcommand*\resetso{} \newcommand*\capsdef{} \newcommand*\capsfont{} \newcommand*\setulcolor{} \newcommand*\setuloverlap{} \newcommand*\setul{} \newcommand*\resetul{} \newcommand*\setuldepth{} \newcommand*\setstcolor{} \newcommand*\sethlcolor{} \newcommand*\so{} \newcommand*\ul{} \newcommand*\st{} \newcommand*\hl{} \newcommand*\caps{} \newcommand*\soulaccent{} \newcommand*\soulregister{} \newcommand*\soulfont{} \newcommand*\soulomit{} \fi % \end{macrocode} % % % % %^^A-------------------------------------------------------------------- % % % % % \noindent % Other packages wouldn't be happy if we reserved piles of \cs{\newtoks} and % \cs{\newdimen}, so we try to get away with their \cs{\...def} counterparts % where possible. % Local registers are always even, while global ones are odd---this is a % \TeX\ convention. % % \begin{macrocode} \newtoks\SOUL@word \newtoks\SOUL@lasttoken \newtoks\SOUL@syllable \newtoks\SOUL@cmds \newtoks\SOUL@buffer \newtoks\SOUL@token \newdimen\SOUL@syllgoal \newdimen\SOUL@syllwidth \newdimen\SOUL@charkern \newdimen\SOUL@hyphkern \newdimen\SOUL@dimen \newdimen\SOUL@dimeni \newcount\SOUL@minus \newcount\SOUL@comma \newcount\SOUL@apo \newcount\SOUL@grave \newskip\SOUL@spaceskip \newif\ifSOUL@ignorespaces % \end{macrocode} % % % % %^^A-------------------------------------------------------------------- % % % % % ^^A\FIXME{\newpage} % \begin{macro}{\soulomit} % \begin{macro}{\SOUL@ignorem} % \begin{macro}{\SOUL@ignore} % \begin{macro}{\SOUL@stopm} % \begin{macro}{\SOUL@stop} % \begin{macro}{\SOUL@relaxm} % \begin{macro}{\SOUL@lowerthanm} % \begin{macro}{\SOUL@hyphenhintm} % These macros are used as markers. To be able to check for such a % marker with \cs{\ifx} we have also to create a macro that contains % the marker. \cs{\SOUL@spc} shall contain a normal space with a % \cs{\catcode} of~10. % % \begin{macrocode} \def\soulomit#1{#1} \def\SOUL@stopM{\SOUL@stop} \let\SOUL@stop\relax \def\SOUL@lowerthan{} \def\SOUL@lowerthanM{\<} \def\SOUL@hyphenhintM{\-} \def\SOUL@n*{\let\SOUL@spc= }\SOUL@n* % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The kernel} % % \begin{macro}{\SOUL@} % This macro is the entry to \soul. Using it does only make % sense after setting up a \soul\ driver. The next token after % the \soul\ command will be assigned to \cs{\SOUL@@}. This can be % some text enclosed in braces, or the name of a macro that contains text. % % \begin{macrocode} \def\SOUL@{% \futurelet\SOUL@@\SOUL@expand } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@expand} % If the first token after the \soul\ command was an opening % brace we start scanning. Otherwise, % if the first token was a macro name, we expand that macro and % call \cs{\SOUL@} with its contents again. Unfortunately, we have to % exclude some macros therein from expansion. % % \begin{macrocode} \def\SOUL@expand{% \ifcat\bgroup\noexpand\SOUL@@ \let\SOUL@n\SOUL@start \else \bgroup \def\\##1##2{\def##2{\noexpand##2}}% \the\SOUL@cmds \SOUL@buffer={% \\\TeX\\\LaTeX\\\soulomit\\\mbox\\\hbox\\\textregistered \\\slash\\\textcircled\\\copyright\\\S\\\,\\\<\\\>\\~% \\\\% }% \def\\##1{\def##1{\noexpand##1}}% \the\SOUL@buffer \let\protect\noexpand \xdef\SOUL@n##1{\noexpand\SOUL@start{\SOUL@@}}% \egroup \fi \SOUL@n } \long\def\SOUL@start#1{{% \let\<\SOUL@lowerthan \let\>\empty \def\soulomit{\noexpand\soulomit}% \gdef\SOUL@eventuallyexhyphen##1{}% \let\SOUL@soeventuallyskip\relax \SOUL@spaceskip=\fontdimen\tw@\font\@plus\fontdimen\thr@@\font \@minus\fontdimen4\font \SOUL@ignorespacesfalse \leavevmode \SOUL@preamble \SOUL@lasttoken={}% \SOUL@word={}% \SOUL@minus\z@ \SOUL@comma\z@ \SOUL@apo\z@ \SOUL@grave\z@ \SOUL@do{#1}% \SOUL@postamble }} \long\def\SOUL@do#1{% \SOUL@scan#1\SOUL@stop } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The scanner} % % \begin{macro}{\SOUL@scan} % This is the entry point for the scanner. It calls \cs{\SOUL@eval} % and will in turn be called by \cs{\SOUL@eval} again for every % new token to be scanned. % % \begin{macrocode} \def\SOUL@scan{% \futurelet\SOUL@@\SOUL@eval } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@eval} % And here it is: the scanner's heart. It cares for quotes and dashes % ligatures and handles all commands that must not be fed to the % analyzer. % % \begin{macrocode} \def\SOUL@eval{% \def\SOUL@n*##1{\SOUL@scan}% \if\noexpand\SOUL@@\SOUL@spc \else \SOUL@ignorespacesfalse \fi \ifnum\SOUL@minus=\thr@@ \SOUL@flushminus \else\ifnum\SOUL@comma=\tw@ \SOUL@flushcomma \else\ifnum\SOUL@apo=\tw@ \SOUL@flushapo \else\ifnum\SOUL@grave=\tw@ \SOUL@flushgrave \fi\fi\fi\fi \ifx\SOUL@@-\else\SOUL@flushminus\fi \ifx\SOUL@@,\else\SOUL@flushcomma\fi \ifx\SOUL@@'\else\SOUL@flushapo\fi \ifx\SOUL@@`\else\SOUL@flushgrave\fi \ifx\SOUL@@-% \advance\SOUL@minus\@ne \else\ifx\SOUL@@,% \advance\SOUL@comma\@ne \else\ifx\SOUL@@'% \advance\SOUL@apo\@ne \else\ifx\SOUL@@`% \advance\SOUL@grave\@ne \else \SOUL@flushminus \SOUL@flushcomma \SOUL@flushapo \SOUL@flushgrave \ifx\SOUL@@\SOUL@stop \def\SOUL@n*{% \SOUL@doword \SOUL@eventuallyexhyphen\null }% \else\ifx\SOUL@@\par \def\SOUL@n*\par{\par\leavevmode\SOUL@scan}% \else\if\noexpand\SOUL@@\SOUL@spc \SOUL@doword \SOUL@eventuallyexhyphen\null \ifSOUL@ignorespaces \else \SOUL@everyspace{}% \fi \def\SOUL@n* {\SOUL@scan}% \else\ifx\SOUL@@\\% \SOUL@doword \SOUL@eventuallyexhyphen\null \SOUL@everyspace{\unskip\nobreak\hfil\break}% \SOUL@ignorespacestrue \else\ifx\SOUL@@~% \SOUL@doword \SOUL@eventuallyexhyphen\null \SOUL@everyspace{\nobreak}% \else\ifx\SOUL@@\slash \SOUL@doword \SOUL@eventuallyexhyphen{/}% \SOUL@exhyphen{/}% \else\ifx\SOUL@@\mbox \def\SOUL@n*{\SOUL@addprotect}% \else\ifx\SOUL@@\hbox \def\SOUL@n*{\SOUL@addprotect}% \else\ifx\SOUL@@\soulomit \def\SOUL@n*\soulomit##1{% \SOUL@doword {\spaceskip\SOUL@spaceskip##1}% \SOUL@scan }% \else\ifx\SOUL@@\break \SOUL@doword \break \else\ifx\SOUL@@\linebreak \SOUL@doword \SOUL@everyspace{\linebreak}% \else\ifcat\bgroup\noexpand\SOUL@@ \def\SOUL@n*{\SOUL@addgroup{}}% \else\ifcat$\noexpand\SOUL@@ \def\SOUL@n*{\SOUL@addmath}% \else \def\SOUL@n*{\SOUL@dotoken}% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \fi\fi\fi\fi \SOUL@n*% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@flushminus} % \begin{macro}{\SOUL@flushcomma} % \begin{macro}{\SOUL@flushapo} % \begin{macro}{\SOUL@flushgrave} % As their names imply, these macros flush special tokens or token % groups to the word register. They don't do anything if the respective % counter equals zero. \cs{\SOUL@minus} does also flush the word % register, because hyphens disturb the analyzer. % % \begin{macrocode} \def\SOUL@flushminus{% \ifcase\SOUL@minus \else \SOUL@doword \SOUL@eventuallyexhyphen{-}% \ifcase\SOUL@minus \or \SOUL@exhyphen{-}% \or \SOUL@exhyphen{--}% \or \SOUL@exhyphen{---}% \fi \SOUL@minus\z@ \fi } \def\SOUL@flushcomma{% \ifcase\SOUL@comma \or \edef\x{\SOUL@word={\the\SOUL@word,}}\x \or \edef\x{\SOUL@word={\the\SOUL@word{{,,}}}}\x \fi \SOUL@comma\z@ } \def\SOUL@flushapo{% \ifcase\SOUL@apo \or \edef\x{\SOUL@word={\the\SOUL@word'}}\x \or \edef\x{\SOUL@word={\the\SOUL@word{{''}}}}\x \fi \SOUL@apo\z@ } \def\SOUL@flushgrave{% \ifcase\SOUL@grave \or \edef\x{\SOUL@word={\the\SOUL@word`}}\x \or \edef\x{\SOUL@word={\the\SOUL@word{{``}}}}\x \fi \SOUL@grave\z@ } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@dotoken} % Command sequences from the \cs{\SOUL@cmds} list are handed over % to \cs{\SOUL@docmd}, everything else is added to \cs{\SOUL@word}, % which will be fed to the analyzer every time a word is completed. % Since \emph{robust} commands come with an additional space, we % have also to examine if there's a space variant. Otherwise we % couldn't detect pre-expanded formerly robust commands. % % \begin{macrocode} \def\SOUL@dotoken#1{% \def\SOUL@@{\SOUL@addtoken{#1}}% \def\\##1##2{% \edef\SOUL@x{\string#1}% \edef\SOUL@n{\string##2}% \ifx\SOUL@x\SOUL@n \def\SOUL@@{\SOUL@docmd{##1}{#1}}% \else \edef\SOUL@n{\string##2\space}% \ifx\SOUL@x\SOUL@n \def\SOUL@@{\SOUL@docmd{##1}{#1}}% \fi \fi }% \the\SOUL@cmds \SOUL@@ } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@docmd} % Here we deal with commands that were registered with \cs{\soulregister} % or \cs{\soulaccent} or were already predefined in \cs{\SOUL@cmds}. % Commands with identifier |9| are accents that are put in a % group with their argument. Identifier |8| is reserved for the \cs{\footnote} % command, and |7| for the \cs{\textsuperscript} or similar commands. % The others are mostly (but not necessarily) % font switching commands, which may (|1|) or may not (|0|) take % an argument. A registered command leads to the current word % buffer being flushed to the analyzer, after which the command % itself is executed. % % Font switching commands which take an argument need special % treatment: They need to increment the level counter, so that % \cs{\SOUL@eval} knows where to stop scanning. Furthermore the % scanner has to be enabled to see the next token after the opening % brace. % % % \begin{macrocode} \def\SOUL@docmd#1#2{% \ifx9#1% \def\SOUL@@{\SOUL@addgroup{#2}}% \else\ifx8#1% \SOUL@doword \def\SOUL@@##1{% \SOUL@token={\footnotemark}% \SOUL@everytoken \SOUL@syllable={\footnotemark}% \SOUL@everysyllable \footnotetext{##1}% \SOUL@doword \SOUL@scan }% \else\ifx7#1% \SOUL@doword \def\SOUL@@##1{% \SOUL@token={#2{##1}}% \SOUL@everytoken \SOUL@syllable={#2{##1}}% \SOUL@everysyllable \SOUL@doword \SOUL@scan }% \else\ifx1#1% \SOUL@doword \def\SOUL@@##1{% #2{\protect\SOUL@do{##1}}% \SOUL@scan }% \else \SOUL@doword #2% \let\SOUL@@\SOUL@scan \fi\fi\fi\fi \SOUL@@ } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@addgroup} % \begin{macro}{\SOUL@addmath} % \begin{macro}{\SOUL@addprotect} % \begin{macro}{\SOUL@addtoken} % The macro names say it all. Each of these macros adds some % token to the word buffer \cs{\SOUL@word}. Setting \cs{\protect} % is necessary to make things like |\so{{a\itshape b}}| work. % % \begin{macrocode} \def\SOUL@addgroup#1#2{% {\let\protect\noexpand \edef\x{\global\SOUL@word={\the\SOUL@word{{\noexpand#1#2}}}}\x}% \SOUL@scan } \def\SOUL@addmath$#1${% {\let\protect\noexpand \edef\x{\global\SOUL@word={\the\SOUL@word{{\hbox{$#1$}}}}}\x}% \SOUL@scan } \def\SOUL@addprotect#1#2{% {\let\protect\noexpand \edef\x{\global\SOUL@word={\the\SOUL@word{{\hbox{#2}}}}}\x}% \SOUL@scan } \def\SOUL@addtoken#1{% \edef\x{\SOUL@word={\the\SOUL@word\noexpand#1}}\x \SOUL@scan } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@exhyphen} % Dealing with explicit hyphens can't be done before we know the % following character, because we need to know if a kerning value % has to be inserted, hence we delay the \cs{\SOUL@everyexhyphen} call. % Unfortunately, the word scanner has no look-ahead mechanism. % % \begin{macrocode} \def\SOUL@exhyphen#1{% \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@hyphkern}{#1}% \gdef\SOUL@eventuallyexhyphen##1{% \SOUL@getkern{#1}{\SOUL@charkern}{##1}% \SOUL@everyexhyphen{#1}% \gdef\SOUL@eventuallyexhyphen####1{}% }% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@cmds} % Here is a list of pre-registered commands that the analyzer % cannot handle, so the scanner has to look after them. Every % entry consists of a handle (\cs{\\}), an identifier and the % macro name. The class identifier can be |9| for accents, % |8| for the \cs{\footnote} command, |7| for the % \cs{\textsuperscript} command, % |0| for commands without arguments and |1| for commands that % take one argument. Commands with two or more arguments are % not supported. % % \begin{macrocode} \SOUL@cmds={% \\9\`\\9\'\\9\^\\9\"\\9\~\\9\=\\9\.% \\9\u\\9\v\\9\H\\9\t\\9\c\\9\d\\9\b\\9\r \\1\emph\\1\textrm\\1\textsf\\1\texttt\\1\textmd\\1\textbf \\1\textup\\1\textsl\\1\textit\\1\textsc\\1\textnormal \\0\rmfamily\\0\sffamily\\0\ttfamily\\0\mdseries\\0\upshape \\0\slshape\\0\itshape\\0\scshape\\0\normalfont \\0\em\\0\rm\\0\bf\\0\it\\0\tt\\0\sc\\0\sl\\0\sf \\0\tiny\\0\scriptsize\\0\footnotesize\\0\small \\0\normalsize\\0\large\\0\Large\\0\LARGE\\0\huge\\0\Huge \\1\MakeUppercase\\7\textsuperscript\\8\footnote \\1\textfrak\\1\textswab\\1\textgoth \\0\frakfamily\\0\swabfamily\\0\gothfamily } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\soulregister} % \begin{macro}{\soulfont} % \begin{macro}{\soulaccent} % Register a font switching command (or some other command) for the % scanner. The first argument is the macro name, the second is % the number of arguments (|0|~or~|1|). Example: |\soulregister{\bold}{0}|. % \cs{\soulaccent} has only one argument---the accent macro name. % Example: |\soulaccent{\~}|. It is a shortcut for |\soulregister{\~}{9}|. % The \cs{\soulfont} command is a synonym for \cs{\soulregister} % and is kept for compatibility reasons. % % \begin{macrocode} \def\soulregister#1#2{{% \edef\x{\global\SOUL@cmds={\the\SOUL@cmds \noexpand\\#2\noexpand#1}}\x }} \def\soulaccent#1{\soulregister{#1}9} \let\soulfont\soulregister % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The analyzer} % % \begin{macro}{\SOUL@doword} % The only way to find out, where a given word can be broken into % syllables, is to let \TeX\ actually typeset the word under conditions % that enforce every possible hyphenation. The result is a paragraph with one % line for every syllable. % % \begin{macrocode} \def\SOUL@doword{% \edef\x{\the\SOUL@word}% \ifx\x\empty \else \SOUL@buffer={}% \setbox\z@\vbox{% \SOUL@tt \hyphenchar\font`\- \hfuzz\maxdimen \hbadness\@M \pretolerance\m@ne \tolerance\@M \leftskip\z@ \rightskip\z@ \hsize1sp \everypar{}% \parfillskip\z@\@plus1fil \hyphenpenalty-\@M \noindent \hskip\z@ \relax \the\SOUL@word}% \let\SOUL@errmsg\SOUL@error \let\-\relax \count@\m@ne \SOUL@analyze \SOUL@word={}% \fi } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \noindent % We store the hyphen width of the |ectt1000| font, % because we will need it in |\SOUL@doword|. (|ectt1000| is a mono-spaced % font, so every other character would have worked, too.) % % \begin{macrocode} \setbox\z@\hbox{\SOUL@tt-} \newdimen\SOUL@ttwidth \SOUL@ttwidth\wd\z@ \def\SOUL@sethyphenchar{% \ifnum\hyphenchar\font=\m@ne \else \char\hyphenchar\font \fi } % \end{macrocode} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@analyze} % This macro decomposes the box that |\SOUL@doword| has built. % Because we have to start at the bottom, we put every % syllable onto the stack and execute ourselves recursively. If there % are no syllables left, we return from the recursion and pick syllable % after syllable from the stack again---this time from top to bottom---and % hand the syllable width |\SOUL@syllgoal| over to |\SOUL@dosyllable|. % All but the last syllable end with the hyphen character, hence % we subtract the hyphen width accordingly. After processing a % syllable we calculate the hyphen kern (i.\,e.~the kerning amount % between the last character and the hyphen). This might be needed % by \cs{\SOUL@everyhyphen}, which we call now. % % \begin{macrocode} \def\SOUL@analyze{{% \setbox\z@\vbox{% \unvcopy\z@ \unskip \unpenalty \global\setbox\@ne=\lastbox}% \ifvoid\@ne \else \setbox\@ne\hbox{\unhbox\@ne}% \SOUL@syllgoal=\wd\@ne \advance\count@\@ne \SOUL@analyze \SOUL@syllwidth\z@ \SOUL@syllable={}% \ifnum\count@>\z@ \advance\SOUL@syllgoal-\SOUL@ttwidth \SOUL@dosyllable \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@hyphkern}% {\SOUL@sethyphenchar}% \SOUL@everyhyphen \else \SOUL@dosyllable \fi \fi }} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@dosyllable} % This macro typesets token after token from \cs{\SOUL@word} % until \cs{\SOUL@syllwidth} has reached % the requested width \cs{\SOUL@syllgoal}. Furthermore the kerning % values are prepared in case \cs{\SOUL@everytoken} needs them. % The \cs{\<} command used by \cs{\so} and \cs{\caps} needs some % special treatment: It has to be checked for, even before % we can end a syllable. % % \begin{macrocode} \def\SOUL@dosyllable{% \SOUL@gettoken \SOUL@eventuallyexhyphen{\the\SOUL@token}% \edef\x{\the\SOUL@token}% \ifx\x\SOUL@hyphenhintM \let\SOUL@n\SOUL@dosyllable \else\ifx\x\SOUL@lowerthanM \SOUL@gettoken \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@charkern} {\the\SOUL@token}% \SOUL@everylowerthan \SOUL@puttoken \let\SOUL@n\SOUL@dosyllable \else\ifdim\SOUL@syllwidth=\SOUL@syllgoal \SOUL@everysyllable \SOUL@puttoken \let\SOUL@n\relax \else\ifx\x\SOUL@stopM \SOUL@errmsg \global\let\SOUL@errmsg\relax \let\SOUL@n\relax \else \setbox\tw@\hbox{\SOUL@tt\the\SOUL@token}% \advance\SOUL@syllwidth\wd\tw@ \global\SOUL@lasttoken=\SOUL@token \SOUL@gettoken \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@charkern} {\the\SOUL@token}% \SOUL@puttoken \global\SOUL@token=\SOUL@lasttoken \SOUL@everytoken \edef\x{\SOUL@syllable={\the\SOUL@syllable\the\SOUL@token}}\x \let\SOUL@n\SOUL@dosyllable \fi\fi\fi\fi \SOUL@n } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@gettoken} % Provide the next token in \cs{\SOUL@token}. If there's already one % in the buffer, use that one first. % % \begin{macrocode} \def\SOUL@gettoken{% \edef\x{\the\SOUL@buffer}% \ifx\x\empty \SOUL@nexttoken \else \global\SOUL@token=\SOUL@buffer \global\SOUL@buffer={}% \fi } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@puttoken} % The possibility to put tokens back makes the scanner design much % cleaner. There's only room for one token, though, so we issue % an error message if \cs{\SOUL@puttoken} is told to put a token % back while the buffer is still in use. Note that \cs{\SOUL@debug} % is actually undefined. This won't hurt as it can only happen % during driver design. No user will ever see this message. % % \begin{macrocode} \def\SOUL@puttoken{% \edef\x{\the\SOUL@buffer}% \ifx\x\empty \global\SOUL@buffer=\SOUL@token \global\SOUL@token={}% \else \SOUL@debug{puttoken called twice}% \fi } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@nexttoken} % \begin{macro}{\SOUL@splittoken} % If the word buffer \cs{\SOUL@word} is empty, deliver a \cs{\SOUL@stop}, % otherwise take the next token. % % \begin{macrocode} \def\SOUL@nexttoken{% \edef\x{\the\SOUL@word}% \ifx\x\empty \SOUL@token={\SOUL@stop}% \else \expandafter\SOUL@splittoken\the\SOUL@word\SOUL@stop \fi } \def\SOUL@splittoken#1#2\SOUL@stop{% \global\SOUL@token={#1}% \global\SOUL@word={#2}% } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@getkern} % Assign the kerning value between the first and the third argument % to the second, which has to be a \cs{\dimen} register. % |\SOUL@getkern{A}{\dimen0}{V}| will assign the kerning value % between `A' and `V' to |\dimen0|. % % \begin{macrocode} \def\SOUL@getkern#1#2#3{% \setbox\tw@\hbox{#1#3}% #2\wd\tw@ \setbox\tw@\hbox{#1\null#3}% \advance#2-\wd\tw@ } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@setkern} % Set a kerning value if it doesn't equal 0\,pt. Of course, we could % also set a zero value, but that would needlessly clutter the % logfile. % % \begin{macrocode} \def\SOUL@setkern#1{\ifdim#1=\z@\else\kern#1\fi} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@error} % This error message will be shown once for every word that couldn't % be reconstructed by \cs{\SOUL@dosyllable}. % % \begin{macrocode} \def\SOUL@error{% \vrule\@height.8em\@depth.2em\@width1em \PackageError{soul}{Reconstruction failed}{% I came across hyphenatable material enclosed in group braces,^^Jwhich I can't handle. Either drop the braces or make the material^^Junbreakable using an \string\mbox\space (\string\hbox). Note that a space^^Jalso counts as possible hyphenation point. See page 4 of the manual.^^JI'm leaving a black square so that you can see where I am right now.% }% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@setup} % This is a null driver, that will be used as the basis for % other drivers. These have then to redefine only interface commands % that shall differ from the default. % % \begin{macrocode} \def\SOUL@setup{% \let\SOUL@preamble\relax \let\SOUL@postamble\relax \let\SOUL@everytoken\relax \let\SOUL@everysyllable\relax \def\SOUL@everyspace##1{##1\space}% \let\SOUL@everyhyphen\relax \def\SOUL@everyexhyphen##1{##1}% \let\SOUL@everylowerthan\relax } \SOUL@setup % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The \so{letterspacing} driver} % % \begin{macro}{\SOUL@sosetletterskip} % A handy helper macro that sets the inter-letter skip with a % draconian \cs{\penalty}. % % \begin{macrocode} \def\SOUL@sosetletterskip{\nobreak\hskip\SOUL@soletterskip} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@sopreamble} % If letterspacing (\cs{\so} or \cs{\caps}) follows a white space, we % replace it with our \syn{outer space}. \LaTeX\ uses |\hskip1sp| as % marker in tabular entries, so we ignore tiny skips. % % \begin{macrocode} \def\SOUL@sopreamble{% \ifdim\lastskip>5sp \unskip \hskip\SOUL@soouterskip \fi \spaceskip\SOUL@soinnerskip } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@sopostamble} % Start the look-ahead scanner \cs{\SOUL@socheck} outside the \cs{\SOUL@} % scope. That's why we make the \syn{outer space} globally available in % \cs{\skip@}. % % \begin{macrocode} \def\SOUL@sopostamble{% \global\skip@=\SOUL@soouterskip \aftergroup\SOUL@socheck } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@socheck} % \begin{macro}{\SOUL@sodoouter} % Read the next token after the \soul\ command into \cs{\SOUL@@} % and examine it. If it's some kind of space, replace it with % \syn{outer space} and the appropriate penalty, else if it's % a closing brace, continue scanning. If it is neither: do nothing. % % \begin{macrocode} \def\SOUL@socheck{% \futurelet\SOUL@@\SOUL@sodoouter } \def\SOUL@sodoouter{% \def\SOUL@n*##1{\hskip\skip@}% \ifcat\egroup\noexpand\SOUL@@ \unkern \egroup \def\SOUL@n*{\afterassignment\SOUL@socheck\let\SOUL@x=}% \else\ifx\SOUL@spc\SOUL@@ \def\SOUL@n* {\hskip\skip@}% \else\ifx~\SOUL@@ \def\SOUL@n*~{\nobreak\hskip\skip@}% \else\ifx\ \SOUL@@ \else\ifx\space\SOUL@@ \else\ifx\@xobeysp\SOUL@@ \else \def\SOUL@n*{}% \let\SOUL@@\relax \fi\fi\fi\fi\fi\fi \SOUL@n*% } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@soeverytoken} % Typeset the token and put an unbreakable inter-letter skip % thereafter. If the token is \cs{\<} then remove the last skip instead. % Gets the character kerning value between the actual and the % next token in \cs{\SOUL@charkern}. % % \begin{macrocode} \def\SOUL@soeverytoken{% \edef\x{\the\SOUL@token}% \ifx\x\SOUL@lowerthanM \else \global\let\SOUL@soeventuallyskip\SOUL@sosetletterskip \the\SOUL@token \SOUL@gettoken \edef\x{\the\SOUL@token}% \ifx\x\SOUL@stopM \else \SOUL@setkern\SOUL@charkern \SOUL@sosetletterskip \SOUL@puttoken \fi \fi } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@soeveryspace} % This macro sets an \syn{inner space}. The argument may contain % penalties and is used for the |~| command. This construction was % needed to make colored underlines work, without having to put % any of the coloring commands into the core. |\kern\z@| prevents % in subsequent \cs{\so} commands that the second discards the % \syn{outer space} of the first. To remove the space simply % use |\unkern\unskip|. % % \begin{macrocode} \def\SOUL@soeveryspace#1{#1\space\kern\z@} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@soeveryhyphen} % Sets implicit hyphens. The kerning value between the current token % and the hyphen character is passed in \cs{\SOUL@hyphkern}. % % \begin{macrocode} \def\SOUL@soeveryhyphen{% \discretionary{% \unkern \SOUL@setkern\SOUL@hyphkern \SOUL@sethyphenchar }{}{}% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@soeveryexhyphen} % Sets the explicit hyphen that is passed as argument. % \cs{\SOUL@soeventuallyskip} equals \cs{\SOUL@sosetletterskip}, % except when a \cs{\<} had been detected. This is necessary because % \cs{\SOUL@soeveryexhyphen} wouldn't know otherwise, that it % follows a~\cs{\<}. % % \begin{macrocode} \def\SOUL@soeveryexhyphen#1{% \SOUL@setkern\SOUL@hyphkern \SOUL@soeventuallyskip \hbox{#1}% \discretionary{}{}{% \SOUL@setkern\SOUL@charkern }% \SOUL@sosetletterskip \global\let\SOUL@soeventuallyskip\relax } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@soeverylowerthan} % Let \cs{\<} remove the last inter-letter skip. Set the kerning value % between the token before and that after the \cs{\<} command. % % % \begin{macrocode} \def\SOUL@soeverylowerthan{% \unskip \unpenalty \global\let\SOUL@soeventuallyskip\relax \SOUL@setkern\SOUL@charkern } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@sosetup} % Override all interface macros by our letterspacing versions. The % only unused macro is \cs{\SOUL@everysyllable}. % % \begin{macrocode} \def\SOUL@sosetup{% \SOUL@setup \let\SOUL@preamble\SOUL@sopreamble \let\SOUL@postamble\SOUL@sopostamble \let\SOUL@everytoken\SOUL@soeverytoken \let\SOUL@everyspace\SOUL@soeveryspace \let\SOUL@everyhyphen\SOUL@soeveryhyphen \let\SOUL@everyexhyphen\SOUL@soeveryexhyphen \let\SOUL@everylowerthan\SOUL@soeverylowerthan } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@setso} % A handy macro for internal use. % % \begin{macrocode} \def\SOUL@setso#1#2#3{% \def\SOUL@soletterskip{#1}% \def\SOUL@soinnerskip{#2}% \def\SOUL@soouterskip{#3}% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\sodef} % This macro assigns the letterspacing skips as well as an optional % font switching command to a command sequence name. \cs{\so} itself % will be defined using this macro. % % \begin{macrocode} \def\sodef#1#2#3#4#5{% \DeclareRobustCommand*#1{\SOUL@sosetup \def\SOUL@preamble{% \SOUL@setso{#3}{#4}{#5}% #2% \SOUL@sopreamble }% \SOUL@ }% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\resetso} % Let \cs{\resetso} define reasonable default values for letterspacing. % % \begin{macrocode} \def\resetso{% \sodef\textso{}{.25em}{.65em\@plus.08em\@minus.06em}% {.55em\@plus.275em\@minus.183em}% } \resetso % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\sloppyword} % Set up a letterspacing macro that inserts slightly stretchable % space between the characters. This can be used to typeset long % words in narrow columns, where ragged paragraphs are undesirable. % See section~\ref{sec:sloppyword}. % % \begin{macrocode} \sodef\sloppyword{% \linepenalty10 \hyphenpenalty10 \adjdemerits\z@ \doublehyphendemerits\z@ \finalhyphendemerits\z@ \emergencystretch.1em}% {\z@\@plus.1em}% {.33em\@plus.11em\@minus.11em}% {.33em\@plus.11em\@minus.11em} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection[The \caps{caps} driver]{The caps driver} % % \begin{macro}{\caps} % Unless run under \LaTeX, make \cs{\caps} just another simple letterspacing % macro that selects a font \cs{\capsfont} (defaulting to \cs{\relax}) but % doesn't have any special capabilities. % % \begin{macrocode} \ifx\documentclass\@undefined \let\capsfont\relax \let\capsreset\relax \def\capsdef#1#2#3#4#5{} \def\capssave#1{} \def\capsselect#1{} \sodef\textcaps{\capsfont} {.028em\@plus.005em\@minus.01em}% {.37em\@plus.1667em\@minus.111em}% {.37em\@plus.1em\@minus.14em} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\capsreset} % \dots\ else, if run under \LaTeX\ prepare a set of macros that % maintain a database with certain letterspacing values for different % fonts. \cs{\capsreset} clears the database and inserts a default rule. % % \begin{macrocode} \else \DeclareRobustCommand*\capsreset{% \let\SOUL@capsbase\empty \SOUL@capsdefault } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\capsdef} % Add an entry to the database, which is of course nothing else than % a \TeX\ macro. See section ``List macros'' of appendix~D in the % \TeX{}book~\cite{DEK} for details. % % \begin{macrocode} \def\capsdef#1#2#3#4#5{{% \toks\z@{\\{#1/#2/#3/#4/#5}}% \toks\tw@=\expandafter{\SOUL@capsbase}% \xdef\SOUL@capsbase{\the\toks\z@\the\toks\tw@}% }} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\capssave} % \begin{macro}{\capsselect} % Save the current database in a macro within the |SOUL@| namespace % and let |\capsselect| restore this database. % % \begin{macrocode} \DeclareRobustCommand*\capssave[1]{% \expandafter\global\expandafter\let \csname SOUL@db@#1\endcsname\SOUL@capsbase } \DeclareRobustCommand*\capsselect[1]{% \expandafter\let\expandafter\SOUL@capsbase \csname SOUL@db@#1\endcsname } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@capsfind} % \begin{macro}{\SOUL@caps} % Go through the database entries and pick the first entry that matches % the currently active font. Then define an internal macro that uses % the respective spacing values in a macro that is equivalent to the % \cs{\textso} command. % % \begin{macrocode} \def\SOUL@capsfind#1/#2/#3/#4/#5/#6/#7/#8/#9/{% \let\SOUL@match=1% \SOUL@chk{#1}\f@encoding \SOUL@chk{#2}\f@family \SOUL@chk{#3}\f@series \SOUL@chk{#4}\f@shape \SOUL@dimchk{#5}\f@size \if\SOUL@match1% \let\\\@gobble \gdef\SOUL@caps{% \SOUL@sosetup \def\SOUL@preamble{\SOUL@setso{#7}{#8}{#9}#6% \SOUL@sopreamble}% \SOUL@}% \fi } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@chk} % Sets the \cs{\SOUL@match} flag if both parameters are equal. % This is used for all \caps{\small NFSS} elements except the font size. % % \begin{macrocode} \def\SOUL@chk#1#2{% \if$#1$% \else \def\SOUL@n{#1}% \ifx#2\SOUL@n\else\let\SOUL@match=0\fi \fi } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@dimchk} % \begin{macro}{\SOUL@rangechk} % We do not only want to check if a given font size |#1| matches |#2|, % but also if it fits into a given range. An omitted lower boundary % is replaced by \cs{\z@} and an omitted upper boundary by \cs{\maxdimen}. % The first of a series of \cs{\SOUL@chk} and \cs{\SOUL@dimchk} % statements, which detects that the arguments don't match, sets the % \cs{\SOUL@match} flag to zero. A value of~1 indicates that an % entry in the font database matches the currently used font. % % \begin{macrocode} \def\SOUL@dimchk#1#2{\if$#1$\else\SOUL@rangechk{#2}#1--\@ne\@@\fi} \def\SOUL@rangechk#1#2-#3-#4\@@{% \count@=#4% \ifnum\count@>\z@ \ifdim#1\p@=#2\p@\else\let\SOUL@match=0\fi \else \SOUL@dimen=\if$#2$\z@\else#2\p@\fi \ifdim#1\p@<\SOUL@dimen\let\SOUL@match=0\fi \SOUL@dimen=\if$#3$\maxdimen\else#3\p@\fi \ifdim#1\p@<\SOUL@dimen\else\let\SOUL@match=0\fi \fi } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\textcaps} % Find a matching entry in the database and start the letterspacing % mechanism with the given spacing values. % % \begin{macrocode} \DeclareRobustCommand*\textcaps{{% \def\\##1{\expandafter\SOUL@capsfind##1/}% \SOUL@capsbase \aftergroup\SOUL@caps }} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@capsdefault} % Define a default database entry and a default font. % % \begin{macrocode} \def\SOUL@capsdefault{% \capsdef{////}% \SOUL@capsdfltfnt {.028em\@plus.005em\@minus.01em}% {.37em\@plus.1667em\@minus.1em}% {.37em\@plus.111em\@minus.14em}% } \let\SOUL@capsdfltfnt\scshape \capsreset \fi % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The \ul{underlining} driver} % % \begin{macro}{\SOUL@ulleaders} % This macro sets the underline under the following \cs{\hskip}. % % \begin{macrocode} \newdimen\SOUL@uldp \newdimen\SOUL@ulht \def\SOUL@ulleaders{% \leaders\hrule\@depth\SOUL@uldp\@height\SOUL@ulht\relax } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@ulunderline} % Set an underline under the given material. It draws the line first, % and the given material afterwards. This is needed for highlighting, % but gives less than optimal results for colored overstriking, which, % however, will hardly ever be used, anyway. % \changes{v3.1}{2023/05/04}{added a kern after leaders to guard against an unskip, issue \#8} % \begin{macrocode} \def\SOUL@ulunderline#1{{% \setbox\z@\hbox{#1}% \SOUL@dimen=\wd\z@ \SOUL@dimeni=\SOUL@uloverlap \advance\SOUL@dimen2\SOUL@dimeni \rlap{% \null \kern-\SOUL@dimeni \SOUL@ulcolor{\SOUL@ulleaders\hskip\SOUL@dimen\kern\z@}% }% \unhcopy\z@ }} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@ulpreamble} % Just set up the line dimensions and the space skip. Normally, % \cs{\spaceskip} is unset and not used by \TeX. We need it, though, % because we feed it to the \cs{\leaders} primitive. % % \begin{macrocode} \def\SOUL@ulpreamble{% \SOUL@uldp=\SOUL@uldepth \SOUL@ulht=-\SOUL@uldp \advance\SOUL@uldp\SOUL@ulthickness \spaceskip\SOUL@spaceskip } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@uleverysyllable} % By using \cs{\SOUL@everysyllable} we don't have to care about % kerning values and get better results for highlighting, where % negative kerning values would otherwise cut off characters. % % \begin{macrocode} \def\SOUL@uleverysyllable{% \SOUL@ulunderline{% \the\SOUL@syllable \SOUL@setkern\SOUL@charkern }% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@uleveryspace} % Set a given penalty and an underlined \cs{\space} equivalent. % The \cs{\null} prevents a nasty gap in |\textfrak| |{a \textswab{b}}|, % while it doesn't seem to hurt in all other cases. I didn't investigate % this. % \changes{v3.1}{2023/05/04}{added a kern after leaders to guard against an unskip, issue \#8} % \begin{macrocode} \def\SOUL@uleveryspace#1{% \SOUL@ulcolor{% #1% \SOUL@ulleaders \hskip\spaceskip \kern\z@ }% \null } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@uleveryhyphen} % If hyphenation takes place, output an underlined hyphen with the % required hyphen kerning value. % % \begin{macrocode} \def\SOUL@uleveryhyphen{% \discretionary{% \unkern \SOUL@ulunderline{% \SOUL@setkern\SOUL@hyphkern \SOUL@sethyphenchar }% }{}{}% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@uleveryexhyphen} % Underline the given hyphen, en-dash, em-dash or \cs{\slash} and care % for kerning. % % \begin{macrocode} \def\SOUL@uleveryexhyphen#1{% \SOUL@setkern\SOUL@hyphkern \SOUL@ulunderline{#1}% \discretionary{}{}{% \SOUL@setkern\SOUL@charkern }% } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@ulcolor} % \begin{macro}{\setulcolor} % Define the underline color or turn off coloring, in which case the lines are not % just colored black, but remain uncolored. This makes them appear % black, nevertheless, and has the advantage, that no Postscript % \cs{\specials} are cluttering the output. % % \begin{macrocode} \let\SOUL@ulcolor\relax \def\setulcolor#1{% \if$#1$ \let\SOUL@ulcolor\relax \else \def\SOUL@ulcolor{\textcolor{#1}}% \fi } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\setuloverlap} % \begin{macro}{\SOUL@uloverlap} % Set the overlap amount, that helps to avoid gaps on sloppy output % devices. % % \begin{macrocode} \def\setuloverlap#1{\def\SOUL@uloverlap{#1}} \setuloverlap{.25pt} % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@ulsetup} % The underlining driver is quite simple. No need for \cs{\SOUL@postamble} % and \cs{\SOUL@everytoken}. % % \begin{macrocode} \def\SOUL@ulsetup{% \SOUL@setup \let\SOUL@preamble\SOUL@ulpreamble \let\SOUL@everysyllable\SOUL@uleverysyllable \let\SOUL@everyspace\SOUL@uleveryspace \let\SOUL@everyhyphen\SOUL@uleveryhyphen \let\SOUL@everyexhyphen\SOUL@uleveryexhyphen } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@textul} % Describing self-explanatory macros is \emph{so} boring! % % \begin{macrocode} \DeclareRobustCommand*\textul{\SOUL@ulsetup\SOUL@} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\setul} % \begin{macro}{\SOUL@uldepth} % \begin{macro}{\SOUL@ulthickness} % Set the underlining dimensions. Either value may be omitted and % lets the respective macro keep its current contents. % % \begin{macrocode} \def\setul#1#2{% \if$#1$\else\def\SOUL@uldepth{#1}\fi \if$#2$\else\def\SOUL@ulthickness{#2}\fi } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\resetul} % Set reasonable default values that fit most latin fonts. % % \begin{macrocode} \def\resetul{\setul{.65ex}{.1ex}} \resetul % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\setuldepth} % This macro sets all designated ``letters'' (\cs{\catcode=11}) or the % given material in a box and sets the underlining dimensions according % to the box depth. % % \begin{macrocode} \def\setuldepth#1{{% \def\SOUL@n{#1}% \setbox\z@\hbox{% \tracinglostchars\z@ \ifx\SOUL@n\empty \count@\z@ \loop \ifnum\catcode\count@=11\char\count@\fi \ifnum\count@<\@cclv \advance\count@\@ne \repeat \else #1% \fi }% \SOUL@dimen\dp\z@ \advance\SOUL@dimen\p@ \xdef\SOUL@uldepth{\the\SOUL@dimen}% }} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The \st{overstriking} driver} % % \begin{macro}{\SOUL@stpreamble} % Striking out is just underlining with a raised line of a different % color. Hence we only need to define the preamble accordingly and % let the underlining preamble finally do its job. Not that colored % overstriking was especially useful, but we want at least to keep % it black while we might want to set underlines in some fancy color. % % \begin{macrocode} \def\SOUL@stpreamble{% \SOUL@dimen\SOUL@ulthickness \SOUL@dimeni=-.5ex \advance\SOUL@dimeni-.5\SOUL@dimen \edef\SOUL@uldepth{\the\SOUL@dimeni}% \let\SOUL@ulcolor\SOUL@stcolor \SOUL@ulpreamble } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@stsetup} % We re-use the whole underlining setup and just replace the preamble % with our modified version. % % \begin{macrocode} \def\SOUL@stsetup{% \SOUL@ulsetup \let\SOUL@preamble\SOUL@stpreamble } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\textst} % These pretzels are making me thirsty \dots % % \begin{macrocode} \DeclareRobustCommand*\textst{\SOUL@stsetup\SOUL@} % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@stcolor} % \begin{macro}{\setstcolor} % Set the overstriking color. This won't be used often, but is required % in cases, where the underlines are colored. You wouldn't want to % overstrike in the same color. Note that overstriking lines are % drawn \emph{beneath} the text, hence bright colors won't look good. % % \begin{macrocode} \let\SOUL@stcolor\relax \def\setstcolor#1{% \if$#1$ \let\SOUL@stcolor\relax \else \def\SOUL@stcolor{\textcolor{#1}}% \fi } % \end{macrocode} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection{The highlighting driver} % % \begin{macro}{\SOUL@hlpreamble} % This is nothing else than overstriking with very thick lines. % % \begin{macrocode} \def\SOUL@hlpreamble{% \setul{}{2.5ex}% \let\SOUL@stcolor\SOUL@hlcolor \SOUL@stpreamble } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\SOUL@hlsetup} % No need to re-invent the wheel. Just use the overstriking setup % with a different preamble. % % \begin{macrocode} \def\SOUL@hlsetup{% \SOUL@stsetup \let\SOUL@preamble\SOUL@hlpreamble } % \end{macrocode} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \begin{macro}{\texthl} % \begin{macro}{\sethlcolor} % \begin{macro}{\SOUL@hlcolor} % Define the highlighting macro and the color setting macro with a % simple default color. Yellow isn't really pleasing, but it's already % predefined by the \package{color} package. % % \begin{macrocode} \DeclareRobustCommand*\texthl{\SOUL@hlsetup\SOUL@} \def\sethlcolor#1{\if$#1$\else\def\SOUL@hlcolor{\textcolor{#1}}\fi} \sethlcolor{yellow} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \subsection*{The package postamble} % % \begin{macro}{\so} % \begin{macro}{\ul} % \begin{macro}{\st} % \begin{macro}{\hl} % \begin{macro}{\caps} % OK, I lied. The short macro names are just abbreviations for their % longer counterpart. Some people might be used to |\text*| style commands % to select a certain font. And then it doesn't hurt to reserve % these early enough. % % \begin{macrocode} \let\so\textso \let\ul\textul \let\st\textst \let\hl\texthl \let\caps\textcaps % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % % %^^A-------------------------------------------------------------------- % % % % % \noindent % When used in an environment other than \LaTeX\ and the \package{german} % package was already loaded, define the double quotes as accent. % % \begin{macrocode} \ifx\documentclass\@undefined \ifx\mdqoff\@undefined \else \soulaccent{"}% \fi \catcode`\@=\atcode % \end{macrocode} % % % % %^^A-------------------------------------------------------------------- % % % % % \noindent % If we have been loaded by a \LaTeX\ environment and the \package{color} % package wasn't also loaded, we disable all colors. Then we add the umlaut accent % |"| if the \package{german} package is present. The quotes character has to % be \cs{\catcode}'d \cs{\active} now, or it won't get recognized later. % The \option{capsdefault} % option overrides the \cs{\caps} driver and lets \cs{\SOUL@} set an underline. % Finally load the local configuration, process the |capsdefault| % option and exit. % % \begin{macrocode} \else \bgroup \catcode`\"\active \AtBeginDocument{% \@ifundefined{color}{% \let\SOUL@color\relax \let\setulcolor\@gobble \let\setstcolor\@gobble \let\sethlcolor\@gobble \let\hl\ul }{} \@ifundefined{mdqoff}{}{\soulaccent{"}} } \egroup \DeclareOption{capsdefault}{% \AtBeginDocument{% \def\SOUL@capsdfltfnt#1{% \SOUL@ulsetup \SOUL@ulpreamble \scshape }% }% } \InputIfFileExists{soul.cfg}% {\PackageInfo{soul}{Local config file soul.cfg used}}{} \ProcessOptions \fi \endinput % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % %^^A-------------------------------------------------------------------- % % % % % \vspace{2explus1fill} %\begin{verbatim} %$Id$ %\end{verbatim} % \Finale % % % ^^A.E.I.O.U.^^ %^^A vim:ts=4:sw=4:et