% \iffalse meta-comment
%
% File: soul.dtx
% Version: 2026-03-06 v3.2
% Info: Permit use of UTF-8 characters in soul
%
% Copyright (C) 2007 Heiko Oberdiek
% Copyright (C) 2016-2026 Oberdiek Package Support Group
%    https://github.com/ho-tex/soul/issues
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any later
% version. This version of this license is in
%    https://www.latex-project.org/lppl/lppl-1-3c.txt
% and the latest version of this license is in
%    https://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of
% LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainers of this work are
% Heiko Oberdiek and the Oberdiek Package Support Group
% https://github.com/ho-tex/soul/issues
%
% The Base Interpreter refers to any `TeX-Format',
% because some files are installed in TDS:tex/generic//.
%
% This work consists of the main source file soul.dtx
% and the derived files
%    soul.sty, soul.pdf, soul.ins,soulutf8.sty
%    soulutf8-test1.tex, soulutf8-test2.tex, soulutf8-test3.tex,
%    soulutf8-test4.tex, soulutf8-test5.tex.
%
% Distribution:
%    CTAN:macros/latex/contrib/soul/soul.dtx
%    CTAN:macros/latex/contrib/soul/soul.pdf
%
% Unpacking:
%           tex soul.ins
%<*driver>
\documentclass{ltxdoc}
\usepackage{holtxdoc}[2011/11/22]
\begin{document}
  \DocInput{soul.dtx}%
\end{document}
%</driver>
% \fi
%
% \title{The \xpackage{soul} package}
% \date{2026-03-06 v3.2}
% \author{Heiko Oberdiek\thanks
% {Please report any issues at \url{https://github.com/ho-tex/soul/issues}}}
%
% \maketitle
%
% \begin{abstract}
% This version is a merge of the original
% package \xpackage{soul} (version 2.5 which contains some small corrections compared to the
% version 2.4 from 2003)
% and the \xpackage{soulutf8} which added some support
% for UTF-8. Namely the input encodings \xfile{utf8.def}
% from package \xpackage{inputenc} and
% package \xpackage{ucs}'s \xfile{utf8x.def} are supported.
% The original \xpackage{soul} package has been renamed to \xpackage{soul-ori} and is still loaded.
% Its documentation is still relevant.
% \end{abstract}
%
% \tableofcontents
%
% \section{Documentation}
%
% This package \xpackage{soul} does not have own options and does not
% define new user commands.
% Any option is passed to package \xpackage{soul-ori} \cite{soul}
% that is loaded first.
% Then some internal macros of \xpackage{soul-ori} are redefined to add
% support for UTF-8.
% The following input encodings are supported:
% \begin{quote}
%   \begin{tabular}{@{}lll@{}}
%     \texttt{utf8} & \LaTeX\ base &
%        \xfile{TDS:tex/latex/base/utf8.def} \cite{utf8}\\
%     \texttt{utf8x} & Package \xpackage{ucs} &
%       \xfile{TDS:tex/latex/ucs/utf8x.def} \cite{ucs}\\
%   \end{tabular}
% \end{quote}
% UTF-8 byte sequences are added as token group to a word, even
% if these UTF-8 characters are some kind of hyphen or space.
% As exception the following three Unicode characters are handled specially:
% \begin{quote}
%   \begin{tabular}{lll}
%     Slot & Name & Action\\
%     \hline
%     \texttt{U+00A0} & NO-BREAK SPACE & like |~|\\
%     \texttt{U+2013} & EN DASH & |--|\\
%     \texttt{U+2014} & EM DASH & |---|
%   \end{tabular}
%
% \subsection{Patch}
%
% Also package \xpackage{soul} tries to patch package \xpackage{soul-ori}
% to improve its behaviour:
% \begin{itemize}
% \item
%   A problem with additional levels of curly braces is fixed.
%   As advantage more implicit kernings are detected.
%   However, the result may be incompatible with the
%   original behaviour of package \xpackage{soul-ori} because
%   of these respected implicit kernings.
% \item
%   \eTeX\ , especially \cs{unexpanded} is supported.
%   This allows a better protection of token groups
%   (|\mbox{|\dots|}|, math, \dots).
% \end{itemize}
% \end{quote}
%
% \subsection{Future}
%
% Currently package \xpackage{soul-ori} does not seem to be
% maintained. Nevertheless if there will be a new version that
% adds support for UTF-8, then this package may become
% obsolete.
%
% \StopEventually{
% }
%
% \section{Implementation}
%    \begin{macrocode}
%<*soulutf8>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{soulutf8}%
  [2026-03-06 v3.2 Permit use of UTF-8 characters in soul (HO)]%
\PackageWarning{soulutf8}
     {This package is obsolete,\MessageBreak
      use the soul package directly. \MessageBreak
      }{}%
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{soul}}%
\ProcessOptions\relax      
\RequirePackage{soul}      
%</soulutf8>
%    \end{macrocode}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \subsection{Reload check and package identification}
%    Reload check, especially if the package is not used with \LaTeX.
%    \begin{macrocode}
\begingroup\catcode61\catcode48\catcode32=10\relax%
  \catcode13=5 % ^^M
  \endlinechar=13 %
  \catcode35=6 % #
  \catcode39=12 % '
  \catcode44=12 % ,
  \catcode45=12 % -
  \catcode46=12 % .
  \catcode58=12 % :
  \catcode64=11 % @
  \catcode123=1 % {
  \catcode125=2 % }
  \expandafter\let\expandafter\x\csname ver@soul.sty\endcsname
  \ifx\x\relax % plain-TeX, first loading
  \else
    \def\empty{}%
    \ifx\x\empty % LaTeX, first loading,
      % variable is initialized, but \ProvidesPackage not yet seen
    \else
      \expandafter\ifx\csname PackageInfo\endcsname\relax
        \def\x#1#2{%
          \immediate\write-1{Package #1 Info: #2.}%
        }%
      \else
        \def\x#1#2{\PackageInfo{#1}{#2, stopped}}%
      \fi
      \x{soul}{The package is already loaded}%
      \aftergroup\endinput
    \fi
  \fi
\endgroup%
%    \end{macrocode}
%    Package identification:
%    \begin{macrocode}
\begingroup\catcode61\catcode48\catcode32=10\relax%
  \catcode13=5 % ^^M
  \endlinechar=13 %
  \catcode35=6 % #
  \catcode39=12 % '
  \catcode40=12 % (
  \catcode41=12 % )
  \catcode44=12 % ,
  \catcode45=12 % -
  \catcode46=12 % .
  \catcode47=12 % /
  \catcode58=12 % :
  \catcode64=11 % @
  \catcode91=12 % [
  \catcode93=12 % ]
  \catcode123=1 % {
  \catcode125=2 % }
  \expandafter\ifx\csname ProvidesPackage\endcsname\relax
    \def\x#1#2#3[#4]{\endgroup
      \immediate\write-1{Package: #3 #4}%
      \xdef#1{#4}%
    }%
  \else
    \def\x#1#2[#3]{\endgroup
      #2[{#3}]%
      \ifx#1\@undefined
        \xdef#1{#3}%
      \fi
      \ifx#1\relax
        \xdef#1{#3}%
      \fi
    }%
  \fi
\expandafter\x\csname ver@soul.sty\endcsname
\ProvidesPackage{soul}%
  [2026-03-06 v3.2 Permit use of UTF-8 characters in soul (HO)]%
%    \end{macrocode}
%
% \subsection{Catcodes}
%
%    \begin{macrocode}
\begingroup\catcode61\catcode48\catcode32=10\relax%
  \catcode13=5 % ^^M
  \endlinechar=13 %
  \catcode123=1 % {
  \catcode125=2 % }
  \catcode64=11 % @
  \def\x{\endgroup
    \expandafter\edef\csname SOuL@AtEnd\endcsname{%
      \endlinechar=\the\endlinechar\relax
      \catcode13=\the\catcode13\relax
      \catcode32=\the\catcode32\relax
      \catcode35=\the\catcode35\relax
      \catcode61=\the\catcode61\relax
      \catcode64=\the\catcode64\relax
      \catcode123=\the\catcode123\relax
      \catcode125=\the\catcode125\relax
    }%
  }%
\x\catcode61\catcode48\catcode32=10\relax%
\catcode13=5 % ^^M
\endlinechar=13 %
\catcode35=6 % #
\catcode64=11 % @
\catcode123=1 % {
\catcode125=2 % }
\def\TMP@EnsureCode#1#2{%
  \edef\SOuL@AtEnd{%
    \SOuL@AtEnd
    \catcode#1=\the\catcode#1\relax
  }%
  \catcode#1=#2\relax
}
\TMP@EnsureCode{10}{12}% ^^J
\TMP@EnsureCode{33}{12}% !
\TMP@EnsureCode{34}{12}% "
\TMP@EnsureCode{36}{3}% $
\TMP@EnsureCode{39}{12}% '
\TMP@EnsureCode{40}{12}% (
\TMP@EnsureCode{41}{12}% )
\TMP@EnsureCode{42}{12}% *
\TMP@EnsureCode{43}{12}% +
\TMP@EnsureCode{44}{12}% ,
\TMP@EnsureCode{45}{12}% -
\TMP@EnsureCode{46}{12}% .
\TMP@EnsureCode{47}{12}% /
\TMP@EnsureCode{58}{12}% :
\TMP@EnsureCode{60}{12}% <
\TMP@EnsureCode{62}{12}% >
\TMP@EnsureCode{91}{12}% [
\TMP@EnsureCode{93}{12}% ]
\TMP@EnsureCode{94}{7}% ^
\TMP@EnsureCode{96}{12}% `
\TMP@EnsureCode{126}\active % ~
\TMP@EnsureCode{128}{12}% ^^80
\TMP@EnsureCode{147}{12}% ^^93
\TMP@EnsureCode{148}{12}% ^^94
\TMP@EnsureCode{160}{12}% ^^a0
\TMP@EnsureCode{194}{12}% ^^c2
\TMP@EnsureCode{226}{12}% ^^e2
\edef\SOuL@AtEnd{\SOuL@AtEnd\noexpand\endinput}
%    \end{macrocode}
%
% \subsection{Loading packages}
%
%    Package \xpackage{soul-ori} uses \cs{documentclass} to detect \LaTeX.
%    \begin{macrocode}
\ifx\documentclass\@undefined
%    \end{macrocode}
%
% \subsubsection{\plainTeX}
%
%    First we check, whether package \xpackage{soul-ori} is already loaded.
%    \begin{macrocode}
  \expandafter\ifx\csname SOUL@\endcsname\relax
%    \end{macrocode}
%    In case of \plainTeX\ package \xpackage{soul-ori} defines some
%    macros in a simple manner that will break the definitions of
%    \xfile{miniltx.tex}, for example. Therefore these macros
%    are first saved and restored afterwards.
%    \begin{macrocode}
    \let\SOuL@orgDeclareRobustCommand\DeclareRobustCommand
    \let\SOuL@orgnewcommand          \newcommand
    \let\SOuL@orgDeclareOption       \DeclareOption
    \let\SOuL@orgPackageError        \PackageError
    \def\SOuL@restorelatexcmds{%
      \let\DeclareRobustCommand\SOuL@orgDeclareRobustCommand
      \let\newcommand          \SOuL@orgnewcommand
      \let\DeclareOption       \SOuL@orgDeclareOption
      \let\PackageError        \SOuL@orgPackageError
    }%
    \input soul-ori.sty\relax
    \SOuL@restorelatexcmds
  \fi
%    \end{macrocode}
%    \begin{macro}{\SOUL@error}
%     Package \xpackage{soul-ori}'s use of \cs{PackageError} is replaced
%     by \cs{@PackageError} of package \xpackage{infwarerr}.
%    \begin{macrocode}
  \input infwarerr.sty\relax
  \let\SOuL@orgSOUL@error\SOUL@error
  \def\SOUL@error{%
    \begingroup
      \let\PackageError\@PackageError
      \SOuL@orgSOUL@error
    \endgroup
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
  \input etexcmds.sty\relax
%    \end{macrocode}
%    \begin{macro}{\@onelevel@sanitize}
%    Define \LaTeX's \cs{@onelevel@sanitize} if not already available.
%    \begin{macrocode}
  \expandafter\ifx\csname @onelevel@sanitize\endcsname\relax
    \def\@onelevel@sanitize#1{%
      \edef#1{%
        \expandafter\strip@prefix\meaning#1%
      }%
    }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\strip@prefix}
%    \begin{macrocode}
    \def\strip@prefix#1>{}%
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
  \fi
\else
%    \end{macrocode}
%
% \subsubsection{\LaTeX}
%    \begin{macrocode}
  \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{soul-ori}}%
  \ProcessOptions\relax
  \RequirePackage{soul-ori}[2023-02-18]%
  \RequirePackage{infwarerr}[2019/12/03]%
  \RequirePackage{etexcmds}[2019/12/15]%
\fi
%    \end{macrocode}
%
% \subsubsection{\eTeX}
%
%    In \plainTeX\ command \cs{+} is an \emph{outer} macro.
%    Therefore numbers are used to avoid problems.
%    \begin{macrocode}
\ifetex@unexpanded
  \catcode33=14 % '!': comment
  \catcode43=9  % '+': ignore
\else
  \catcode33=9  % '!': ignore
  \catcode43=14 % '+': comment
\fi
%    \end{macrocode}
%
% \subsection{Macro for redefinitions}
%
%    \begin{macro}{\SOuL@redefine}
%    \begin{macrocode}
\def\SOuL@redefine#1{%
  \begingroup
    \def\SOuL@cmd{#1}%
    \afterassignment\SOuL@cmdcheck
    \def\SOuL@temp
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOuL@cmdcheck}
%    \begin{macrocode}
\def\SOuL@cmdcheck{%
    \expandafter\ifx\SOuL@cmd\SOuL@temp
    \else
      \edef\SOuL@temp*{\expandafter\string\SOuL@cmd}%
      \@PackageWarningNoLine{soul}{%
        Command \SOuL@temp* has changed.\MessageBreak
        Supported versions of package `soul-ori': 2021/12/14.\MessageBreak
        Depending on the unknown changes the redefinition\MessageBreak
        of \SOuL@temp* may not behave correctly%
      }%
    \fi
  \expandafter\endgroup
  \expandafter\def\SOuL@cmd
}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Redefinition of \cs{SOUL@eval}}
%
%    \begin{macro}{\SOUL@eval}
%    Macro \cs{SOUL@eval} is redefined to add detection of
%    the first byte of a UTF-8 sequence. Because \cs{SOUL@eval}
%    is overwritten, a warning is issued, if the contents of
%    \cs{SOUL@eval} is not as expected.
%    \begin{macrocode}
\SOuL@redefine\SOUL@eval{%
%    \end{macrocode}
%    First the expected definition.
%    \begin{macrocode}
  \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}
%    Now the redefined version follows.
%    \begin{macrocode}
  \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
%    \end{macrocode}
%    The current token is examined to detect the start of
%    a UTF-8 sequence.
%    \begin{macrocode}
      \SOuL@analyzeutfviii
      \ifcase\SOuL@octets
        \SOuL@analyzeutfviiix
      \fi
      \ifcase\SOuL@octets
        \def\SOUL@n*{\SOUL@dotoken}%
      \or % 1
      \or % 2
        \def\SOUL@n*{\SOuL@addtwooctets}%
      \or % 3
        \def\SOUL@n*{\SOuL@addthreeoctets}%
      \or % 4
        \def\SOUL@n*{\SOuL@addfouroctets}%
      \fi
    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
  \fi\fi\fi\fi
  \SOUL@n*%
}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{UTF-8 analysis}
%
% \subsubsection{Help strings}
%
%    \begin{macrocode}
\def\SOuL@defsanitizedstring#1#2{%
  \expandafter\def\csname SOuL@string#1\endcsname{#2}%
  \expandafter\@onelevel@sanitize\csname SOuL@string#1\endcsname
}
\SOuL@defsanitizedstring{UTFviii}{UTFviii@}
\SOuL@defsanitizedstring{octets}{@octets}
\SOuL@defsanitizedstring{two}{two}
\SOuL@defsanitizedstring{three}{three}
\SOuL@defsanitizedstring{four}{four}
\SOuL@defsanitizedstring{macrocolon}{macro:}
\SOuL@defsanitizedstring{csnameu}{csname u8-}
\SOuL@defsanitizedstring{undeferr}{utf@viii@undeferr}
\def\SOuL@stringendash{^^e2^^80^^93}
\def\SOuL@stringemdash{^^e2^^80^^94}
\def\SOuL@stringnobreakspace{^^c2^^a0}
\edef\SOuL@charhash{\string #}
\edef\SOuL@chartwo{\string 2}
\edef\SOuL@charthree{\string 3}
\def\SOuL@empty{}
%    \end{macrocode}
%
% \subsubsection{Support for \xfile{utf8.def}}
%
%    \begin{macro}{\SOuL@analyzeutfviii}
%    \begin{macrocode}
\begingroup
  \edef\x{\endgroup
    \def\noexpand\SOuL@analyzeutfviii{%
      \noexpand\expandafter\noexpand\SOuL@checkutfviii
      \noexpand\meaning\noexpand\SOUL@@
      \SOuL@stringUTFviii\SOuL@stringoctets
      \noexpand\@nil
    }%
    \def\noexpand\SOuL@checkutfviii
      ##1\SOuL@stringUTFviii##2\SOuL@stringoctets##3\noexpand\@nil
  }%
\x{%
  \def\SOuL@temp{#2}%
  \chardef\SOuL@octets=%
      \ifx\SOuL@temp\SOuL@stringtwo
        \tw@
      \else\ifx\SOuL@temp\SOuL@stringthree
        \thr@@
      \else\ifx\SOuL@temp\SOuL@stringfour
        4 %
      \else
        \z@
      \fi\fi\fi
}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Support for \xfile{utf8x.def}}
%
%    \begin{macro}{\SOuL@analyzeutfviiix}
%    \begin{macrocode}
\begingroup
  \edef\x{\endgroup
    \def\noexpand\SOuL@analyzeutfviiix{%
      \noexpand\expandafter\noexpand\SOuL@checkutfviiix
      \noexpand\meaning\noexpand\SOUL@@
      \SOuL@stringmacrocolon\SOuL@charhash1{}{}{}{}%
      \SOuL@stringcsnameu\SOuL@stringundeferr
      \noexpand\@nil
    }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOuL@checkutfviiix}
%    \begin{macrocode}
    \def\noexpand\SOuL@checkutfviiix
      ##1\SOuL@stringmacrocolon\SOuL@charhash1##2##3##4##5##6%
      \SOuL@stringcsnameu##7\SOuL@stringundeferr##8\noexpand\@nil
  }%
\x{%
  \def\SOuL@temp{#7}%
  \ifx\SOuL@temp\SOuL@empty
    \chardef\SOuL@octets=\z@
  \else
    \def\SOuL@temp{#5}%
    \ifx\SOuL@temp\SOuL@charthree
      \chardef\SOuL@octets=4 %
    \else
      \def\SOuL@temp{#3}%
      \ifx\SOuL@temp\SOuL@chartwo
        \chardef\SOuL@octets=\thr@@
      \else
        \chardef\SOuL@octets=\tw@
      \fi
    \fi
  \fi
}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Actions for UTF-8 sequences}
%
%    \begin{macro}{\SOuL@addtwooctets}
%    \begin{macrocode}
\def\SOuL@addtwooctets#1#2{%
  \def\SOuL@temp{#1#2}%
  \@onelevel@sanitize\SOuL@temp
  \ifx\SOuL@temp\SOuL@stringnobreakspace
    \SOUL@doword
    \SOUL@eventuallyexhyphen\null
    \SOUL@everyspace{\nobreak}%
    \let\SOuL@next\SOUL@scan
  \else
    \def\SOuL@next{%
!     \SOUL@addtoken{{\noexpand#1\noexpand#2}}%
+     \SOUL@addtoken{{\etex@unexpanded{#1#2}}}%
    }%
  \fi
  \SOuL@next
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOuL@addthreeoctets}
%    \begin{macrocode}
\def\SOuL@addthreeoctets#1#2#3{%
  \def\SOuL@temp{#1#2#3}%
  \@onelevel@sanitize\SOuL@temp
  \ifx\SOuL@temp\SOuL@stringendash
    \SOUL@doword
    \SOUL@eventuallyexhyphen{-}%
    \SOUL@exhyphen{--}%
    \let\SOuL@next\SOUL@scan
  \else
    \ifx\SOuL@temp\SOuL@stringemdash
      \SOUL@doword
      \SOUL@eventuallyexhyphen{-}%
      \SOUL@exhyphen{---}%
      \let\SOuL@next\SOUL@scan
    \else
      \def\SOuL@next{%
!       \SOUL@addtoken{{\noexpand#1\noexpand#2\noexpand#3}}%
+       \SOUL@addtoken{{\etex@unexpanded{#1#2#3}}}%
      }%
    \fi
  \fi
  \SOuL@next
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOuL@addfouroctets}
%    \begin{macrocode}
\def\SOuL@addfouroctets#1#2#3#4{%
! \SOUL@addtoken{{\noexpand#1\noexpand#2\noexpand#3\noexpand#4}}%
+ \SOUL@addtoken{{\etex@unexpanded{#1#2#3#4}}}%
}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Redefinition of \cs{SOUL@splittoken}}
%
%    \begin{macro}{\SOUL@splittoken}
%    Macro \cs{SOUL@splittoken} separates the first token
%    or token group from a word and redefines the word to contain
%    the remaining tokens. However if the remaining tokens are
%    a token group, then the curly braces will be removed and
%    the token group is split by the next call of \cs{SOUL@splittoken}.
%    The redefinition avoids the removal of curly braces around the
%    remaining tokens.
%    \begin{macrocode}
\SOuL@redefine\SOUL@splittoken#1#2\SOUL@stop{%
  \global\SOUL@token={#1}%
  \global\SOUL@word={#2}%
}#1{%
  \global\SOUL@token={#1}%
  \SOuL@remainingtoken\relax
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOuL@remainingtoken}
%    \begin{macrocode}
\long\def\@gobble#1{}
\def\SOuL@remainingtoken#1\SOUL@stop{%
  \global\SOUL@word=\expandafter{\@gobble#1}%
}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Patches}
%
%    The fixed \cs{SOUL@splittoken} allows to remove the double
%    sets of curly braces in other macros of package \xpackage{soul-ori}.
%    The benefit is that implicit kernings are more often detected
%    and fixes a bug in package \xpackage{soul-ori}. The disadvantage is
%    incompatibility. The width of the resulting strings may change.
%    \begin{macro}{\SOUL@flushcomma}
%    \begin{macrocode}
\SOuL@redefine\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@
}{%
  \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@
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOUL@flushapo}
%    \begin{macrocode}
\SOuL@redefine\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@
}{%
  \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@
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOUL@flushgrave}
%    \begin{macrocode}
\SOuL@redefine\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@
}{%
  \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}
%    \begin{macro}{\SOUL@addgroup}
%    \begin{macrocode}
\SOuL@redefine\SOUL@addgroup#1#2{%
  {%
    \let\protect\noexpand
    \edef\x{%
      \global\SOUL@word={%
        \the\SOUL@word
        {{\noexpand#1#2}}%
      }%
    }%
    \x
  }%
  \SOUL@scan
}#1#2{%
  \begingroup
    \let\protect\noexpand
    \edef\x{\endgroup
      \SOUL@word={%
        \the\SOUL@word
!       {\noexpand#1{#2}}%
+       {\etex@unexpanded{#1{#2}}}%
      }%
    }%
  \x
  \SOUL@scan
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOUL@addmath}
%    \begin{macrocode}
\SOuL@redefine\SOUL@addmath$#1${%
  {%
    \let\protect\noexpand
    \edef\x{%
      \global\SOUL@word={%
        \the\SOUL@word
        {{\hbox{$#1$}}}%
      }%
    }%
    \x
  }%
  \SOUL@scan
}$#1${%
  \begingroup
    \let\protect\noexpand
    \edef\x{\endgroup
      \SOUL@word={%
        \the\SOUL@word
!       {\hbox{$#1$}}%
+       {\etex@unexpanded{\hbox{$#1$}}}%
      }%
    }%
  \x
  \SOUL@scan
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\SOUL@addprotect}
%    \begin{macrocode}
\SOuL@redefine\SOUL@addprotect#1#2{%
  {%
    \let\protect\noexpand
    \edef\x{%
      \global\SOUL@word={%
        \the\SOUL@word
        {{\hbox{#2}}}%
      }%
    }%
    \x
  }%
  \SOUL@scan
}#1#2{%
  \begingroup
    \let\protect\noexpand
    \edef\x{\endgroup
      \SOUL@word={%
        \the\SOUL@word
!       {\hbox{#2}}%
+       {\etex@unexpanded{\hbox{#2}}}%
      }%
    }%
  \x
  \SOUL@scan
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\SOUL@addtoken}
%    \begin{macrocode}
+ \SOuL@redefine\SOUL@addtoken#1{%
+   \edef\x{%
+     \SOUL@word={%
+       \the\SOUL@word
+       \noexpand#1%
+     }%
+   }%
+   \x
+   \SOUL@scan
+ }#1{%
+   \edef\x{%
+     \SOUL@word={%
+       \the\SOUL@word
+       \etex@unexpanded{#1}%
+     }%
+   }%
+   \x
+   \SOUL@scan
+ }%
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macrocode}
\SOuL@AtEnd%
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
% \section{Installation}
%
% \subsection{Download}
%
% \paragraph{Package.} This package is available on
% CTAN\footnote{\CTANpkg{soul}}:
% \begin{description}
% \item[\CTAN{macros/latex/contrib/soul/soul.dtx}] The source file.
% \item[\CTAN{macros/latex/contrib/soul/soul-ori.dtx}] The source file.
% \item[\CTAN{macros/latex/contrib/soul/soul.pdf}] Documentation.
% \end{description}
%
%
% \subsection{Package installation}
% 
%  Install the package with the package manager of your TeX system.
%  If you want to do it manually:
%
% \paragraph{Unpacking.}
% Run tex or \LaTeX{} on the \xfile{.ins} file
% \begin{quote}
%   \verb|tex soul.ins|
% \end{quote}
%
% \paragraph{TDS.} Now the different files must be moved into
% the different directories in your installation TDS tree
% (also known as \xfile{texmf} tree):
% \begin{quote}
% \def\t{^^A
% \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}}
%   soul.sty & tex/generic/soul/soul.sty\\
%   soul-ori.sty & tex/generic/soul/soul-ori.sty\\   
%   soulutf8.sty & tex/latex/soul/soulutf8.sty\\      
%   soul.pdf & doc/generic/soul/soul.pdf\\
%   soul-ori.pdf & doc/generic/soul/soul-ori.pdf\\
%   soul.dtx    & source/generic/soul/soul.dtx\\
%   soulori.dtx & source/generic/soul/soul-ori.dtx\\
% \end{tabular}^^A
% }^^A
% \sbox0{\t}^^A
% \ifdim\wd0>\linewidth
%   \begingroup
%     \advance\linewidth by\leftmargin
%     \advance\linewidth by\rightmargin
%   \edef\x{\endgroup
%     \def\noexpand\lw{\the\linewidth}^^A
%   }\x
%   \def\lwbox{^^A
%     \leavevmode
%     \hbox to \linewidth{^^A
%       \kern-\leftmargin\relax
%       \hss
%       \usebox0
%       \hss
%       \kern-\rightmargin\relax
%     }^^A
%   }^^A
%   \ifdim\wd0>\lw
%     \sbox0{\small\t}^^A
%     \ifdim\wd0>\linewidth
%       \ifdim\wd0>\lw
%         \sbox0{\footnotesize\t}^^A
%         \ifdim\wd0>\linewidth
%           \ifdim\wd0>\lw
%             \sbox0{\scriptsize\t}^^A
%             \ifdim\wd0>\linewidth
%               \ifdim\wd0>\lw
%                 \sbox0{\tiny\t}^^A
%                 \ifdim\wd0>\linewidth
%                   \lwbox
%                 \else
%                   \usebox0
%                 \fi
%               \else
%                 \lwbox
%               \fi
%             \else
%               \usebox0
%             \fi
%           \else
%             \lwbox
%           \fi
%         \else
%           \usebox0
%         \fi
%       \else
%         \lwbox
%       \fi
%     \else
%       \usebox0
%     \fi
%   \else
%     \lwbox
%   \fi
% \else
%   \usebox0
% \fi
% \end{quote}
% If you have a \xfile{docstrip.cfg} that configures and enables \docstrip's
% TDS installing feature, then some files can already be in the right
% place, see the documentation of \docstrip.
%
% \subsection{Refresh file name databases}
%
% If your \TeX~distribution
% (\TeX\,Live, \mikTeX, \dots) relies on file name databases, you must refresh
% these. For example, \TeX\,Live\ users run \verb|texhash| or
% \verb|mktexlsr|.
%
%
% \begin{thebibliography}{9}
%
% \bibitem{soul}
%   Melchior Franz: \textit{The \xpackage{soul} package};
%   2003/11/17;\\
%   \CTANpkg{soul}.
%
% \bibitem{ucs}
%   Dominique P. G. Unruh: \textit{\xpackage{ucs.sty} -- Unicode Support};
%   2004/10/17;\\
%   \CTANpkg{unicode}.
%
% \bibitem{utf8}
%   Frank Mittelbach, Chris Rowley:
%   \textit{Providing some UTF-8 support via \xpackage{inputenc}};
%   2006/03/30;\\
%   \CTAN{macros/latex/base/utf8ienc.dtx}.
%
% \end{thebibliography}
%
% \begin{History}
%   \begin{Version}{2007/09/09 v1.0}
%   \item
%     First version.
%   \end{Version}
%   \begin{Version}{2016/05/16 v1.1}
%   \item
%     Documentation updates.
%   \end{Version}
%   \begin{Version}{2019/12/15 v1.2}
%   \item
%     Documentation updates.
%   \end{Version}
%   \begin{Version}{2023-02-18 v3.0}
%   \item merged soulutf8 and the original soul into one package.
%   \end{Version}
%   \begin{Version}{2023-06-14 v3.1}
%   \item Updated
%   \end{Version}
%   \begin{Version}{2026-03-06 v3.2}
%   \item Updated
%   \end{Version}
% \end{History}
%
% \PrintIndex
%
% \Finale
\endinput
