\def\titlecapsVersionNumber{1.3}
\def\titlecapsVersionDate{2022/04/12}
\ProvidesPackage{titlecaps}
[\titlecapsVersionDate\ \titlecapsVersionNumber\
 Routines for setting rich-text input into Titling Caps]
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c 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 Maintainer of this work is Steven B. Segletes.
%
% V1.1  -Typographical corrections to docs.
%       -Missing % added on line 356
% V1.2  -Replaced all occurrences of \roman with \romannumeral\value
%       -Found two lines needing a trailing %
%       -Added a trailing space following invocations of \catcode
% V1.3  -Converted a number of \ifthenelse to corresponding TeX level
%        \ifx, \ifnum, and \if syntax
%       -Converted a number of \protected@edef to appropriately 
%        expanded \def syntax.
%
\usepackage{ifnextok}
\usepackage{ifthen}
\newcounter{lcword@index}
\newcounter{word@count}
\newcounter{lc@words}
\let\SaveHardspace~
\def\SoftSpace{ }
\catcode`\^^00=12 %
\def\cmd@flag{^^00} % FLAGS END-OF-COMMAND; NEXT CHAR CAPPED
\def\def@x#1#2{\expandafter\def\expandafter#1\expandafter{#2}}
\def\def@xx#1#2{\expandafter\def@x\expandafter#1\expandafter{#2}}
\def\def@xxx#1#2{\expandafter\def@xx\expandafter#1\expandafter{#2}}

\let\sv@textup\textup
\let\sv@textit\textit
\let\sv@textsc\textsc
\let\sv@textsl\textsl
\let\sv@textmd\textmd
\let\sv@textbf\textbf
\let\sv@textrm\textrm
\let\sv@textsf\textsf
\let\sv@texttt\texttt
\let\sv@itshape\itshape
\let\sv@upshape\upshape
\let\sv@scshape\scshape
\let\sv@slshape\slshape
\let\sv@bfseries\bfseries
\let\sv@mdseries\mdseries
\let\sv@sffamily\sffamily
\let\sv@rmfamily\rmfamily
\let\sv@ttfamily\ttfamily

% THESE ARE THE PUNCTUATION MARKS SCREENED OUT FOR 
% LOWER CASE WORD SEARCH
\newcommand\kill@punct{%
\catcode`.=9 %
\catcode`,=9 %
\catcode`:=9 %
\catcode`;=9 %
\catcode`(=9 %
\catcode`)=9 %
\catcode`[=9 %
\catcode`]=9 %
\catcode`?=9 %
\catcode`!=9 %
\catcode``=9 %
\catcode`'=9 %
}

\newcommand\restore@punct{%
\catcode`.=12 %
\catcode`,=12 %
\catcode`:=12 %
\catcode`;=12 %
\catcode`(=12 %
\catcode`)=12 %
\catcode`[=12 %
\catcode`]=12 %
\catcode`?=12 %
\catcode`!=12 %
\catcode``=12 %
\catcode`'=12 %
}

\def\add@space{\def@xx\@thestring{\expandafter\@thestring\SoftSpace}}


% PRIMUS IS FOR BEGINNING-OF-STRING TITLE-CAPPING (1st WORD OVERRIDES
% PREDEFINED LOWER CASE)
\newcommand\redefine@primus{%
  \def\textup##1{\relax\bgroup\sv@upshape\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textit##1{\relax\bgroup\sv@itshape\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textsc##1{\relax\bgroup\sv@scshape\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textsl##1{\relax\bgroup\sv@slshape\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textmd##1{\relax\bgroup\sv@mdseries\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textbf##1{\relax\bgroup\sv@bfseries\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textrm##1{\relax\bgroup\sv@rmfamily\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textsf##1{\relax\bgroup\sv@sffamily\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\texttt##1{\relax\bgroup\sv@ttfamily\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\textnc##1{\relax\bgroup\titlecap[s]{{\cmd@flag##1}}\egroup}%
  \def\itshape{\relax\sv@itshape\cmd@flag}%
  \def\upshape{\relax\sv@upshape\cmd@flag}%
  \def\scshape{\relax\sv@scshape\cmd@flag}%
  \def\slshape{\relax\sv@slshape\cmd@flag}%
  \def\bfseries{\relax\sv@bfseries\cmd@flag}%
  \def\mdseries{\relax\sv@mdseries\cmd@flag}%
  \def\sffamily{\relax\sv@sffamily\cmd@flag}%
  \def\rmfamily{\relax\sv@rmfamily\cmd@flag}%
  \def\ttfamily{\relax\sv@ttfamily\cmd@flag}%
}
% SECONDUS IS FOR MIDSTRING TITLE-CAPPING (WHERE PREDEFINED LOWER 
% CASE CAN PREVAIL)
\newcommand\redefine@secundus{%
  \def\textup##1{\relax\bgroup\sv@upshape\titlecap[s]{{##1}}\egroup}%
  \def\textit##1{\relax\bgroup\sv@itshape\titlecap[s]{{##1}}\egroup}%
  \def\textsc##1{\relax\bgroup\sv@scshape\titlecap[s]{{##1}}\egroup}%
  \def\textsl##1{\relax\bgroup\sv@slshape\titlecap[s]{{##1}}\egroup}%
  \def\textmd##1{\relax\bgroup\sv@mdseries\titlecap[s]{{##1}}\egroup}%
  \def\textbf##1{\relax\bgroup\sv@bfseries\titlecap[s]{{##1}}\egroup}%
  \def\textrm##1{\relax\bgroup\sv@rmfamily\titlecap[s]{{##1}}\egroup}%
  \def\textsf##1{\relax\bgroup\sv@sffamily\titlecap[s]{{##1}}\egroup}%
  \def\texttt##1{\relax\bgroup\sv@ttfamily\titlecap[s]{{##1}}\egroup}%
  \def\textnc##1{\relax\bgroup\titlecap[s]{{##1}}\egroup}%
  \def\itshape{\relax\sv@itshape\cmd@flag}%
  \def\upshape{\relax\sv@upshape\cmd@flag}%
  \def\scshape{\relax\sv@scshape\cmd@flag}%
  \def\slshape{\relax\sv@slshape\cmd@flag}%
  \def\bfseries{\relax\sv@bfseries\cmd@flag}%
  \def\mdseries{\relax\sv@mdseries\cmd@flag}%
  \def\sffamily{\relax\sv@sffamily\cmd@flag}%
  \def\rmfamily{\relax\sv@rmfamily\cmd@flag}%
  \def\ttfamily{\relax\sv@ttfamily\cmd@flag}%
}

% TERTIUS IS USED FOR STRIPPING OUT MACROS, SO THAT LOWER-CASE
% WORDS CAN BE FOUND
\newcommand\redefine@tertius{%
  \def\textup##1{\bgroup{##1}\egroup}%
  \def\textit##1{\bgroup{##1}\egroup}%
  \def\textsc##1{\bgroup{##1}\egroup}%
  \def\textsl##1{\bgroup{##1}\egroup}%
  \def\textmd##1{\bgroup{##1}\egroup}%
  \def\textbf##1{\bgroup{##1}\egroup}%
  \def\textrm##1{\bgroup{##1}\egroup}%
  \def\textsf##1{\bgroup{##1}\egroup}%
  \def\texttt##1{\bgroup{##1}\egroup}%
  \def\textnc##1{\bgroup{##1}\egroup}%
  \def\itshape{}%
  \def\itshape{}%
  \def\upshape{}%
  \def\scshape{}%
  \def\slshape{}%
  \def\bfseries{}%
  \def\mdseries{}%
  \def\sffamily{}%
  \def\rmfamily{}%
  \def\ttfamily{}%
}

\newcommand\un@define{%
  \let\textup\sv@textup%
  \let\textit\sv@textit%
  \let\textsc\sv@textsc%
  \let\textsl\sv@textsl%
  \let\textmd\sv@textmd%
  \let\textbf\sv@textbf%
  \let\textrm\sv@textrm%
  \let\textsf\sv@textsf%
  \let\texttt\sv@texttt%
  \def\textnc##1{##1}%
  \let\itshape\sv@itshape%
  \let\upshape\sv@upshape%
  \let\scshape\sv@scshape%
  \let\slshape\sv@slshape%
  \let\bfseries\sv@bfseries%
  \let\mdseries\sv@mdseries%
  \let\sffamily\sv@sffamily%
  \let\rmfamily\sv@rmfamily%
  \let\ttfamily\sv@ttfamily%
}

% USES EQUIVALENT NAMES FROM stringstrings PACKAGE
\newcommand\usestringstringsnames{%
  \let\addlcwords\Addlcwords%
  \let\resetlcwords\Resetlcwords%
  \let\addlcword\add@lcword%
  \let\getargs\get@argsC%
  \newcommand\capitalizetitle[2][v]{%
    \if v##1\titlecap[P]{##2}\else\titlecap@q[P]{##2}\fi%
  }%
}

% STORE (DON'T EXECUTE) \titlecap COMMAND & ARGUMENT
\newcommand\titlecap@q[2][P]{%
  \def\thestring{\titlecap[#1]{#2}}%
}

% RESET PREDESIGNATED LOWERCASE WORD LIST
\setcounter{lc@words}{0}
\newcommand\Resetlcwords[0]{\setcounter{lc@words}{0}}

% ADD WORDS TO PREDESIGNATED LOWERCASE WORD LIST
\newcommand\Addlcwords[1]{%
  \get@argsC{#1}%
  \setcounter{lcword@index}{0}%
  \whiledo{\value{lcword@index} < \narg}{%
    \addtocounter{lcword@index}{1}%
    \add@lcword{\csname arg\romannumeral\value{lcword@index}\endcsname}%
  }%
}

\newcommand\add@lcword[1]{%
  \addtocounter{lc@words}{1}%
  \expandafter\def@xx\csname lcword\romannumeral\value{lc@words}\endcsname{#1}%
}

% SEARCH TERTIUS CONVERTED ARGUMENT FOR LOWERCASE WORDS, SET FLAG
% FOR EACH WORD (T = FOUND IN LIST, F= NOT FOUND IN LIST)
\newcommand\seek@lcwords[1]{%
\kill@punct%
  \setcounter{word@count}{0}%
  \whiledo{\value{word@count} < \narg}{%
    \addtocounter{word@count}{1}%
    \def@xx\current@word{%
      \csname arg\romannumeral\value{word@count}\endcsname}%
    \def\found@word{F}%
    \setcounter{lcword@index}{0}%
    \expandafter\def\csname%
            found@word\romannumeral\value{word@count}\endcsname{F}%
    \whiledo{\value{lcword@index} < \value{lc@words}}{%
      \addtocounter{lcword@index}{1}%
      \def@xx\current@lcword{%
        \csname lcword\romannumeral\value{lcword@index}\endcsname}%
%% THE FOLLOWING THREE LINES ARE FROM DAVID CARLISLE
  \protected@edef\tmp{\noexpand\scantokens{\def\noexpand\tmp%
   {\noexpand\ifthenelse{\noexpand\equal{\current@word}{\current@lcword}}}}}%
  \tmp\ifhmode\unskip\fi\tmp
%%
      {\expandafter\def\csname%
            found@word\romannumeral\value{word@count}\endcsname{T}%
       \setcounter{lcword@index}{\value{lc@words}}}%
      {}%
    }%
  }%
\if P#1\def\found@wordi{F}\fi%
\restore@punct%
}

% THE TITLECAP ROUTINE
\newcommand\titlecap[2][P]{%
  \digest@sizes%
  \if T\converttilde\def~{ }\fi%
  \redefine@tertius%
  \get@argsC{#2}%
  \seek@lcwords{#1}%
  \if P#1%
    \redefine@primus%
    \get@argsC{#2}%
    \def@x\primus@argi{\argi}%
  \else%
  \fi%
  \setcounter{word@count}{0}%
  \redefine@secundus%
  \def\@thestring{}%
  \get@argsC{#2}%
  \if P#1\def@x\argi{\primus@argi}\fi%
  \whiledo{\value{word@count} < \narg}{%
    \addtocounter{word@count}{1}%
    \if F\csname found@word\romannumeral\value{word@count}\endcsname%
      \title@word{%
        \csname arg\romannumeral\value{word@count}\endcsname}%
      \expandafter\def@x\csname%
           arg\romannumeral\value{word@count}\endcsname{\@thestring}%
    \else%
      \notitle@word{%
        \csname arg\romannumeral\value{word@count}\endcsname}%
      \expandafter\def@x\csname%
           arg\romannumeral\value{word@count}\endcsname{\@thestring}%
    \fi%
  }%
  \def\@thestring{}%
  \setcounter{word@count}{0}%
  \whiledo{\value{word@count} < \narg}{%
    \addtocounter{word@count}{1}%
    \ifnum\value{word@count} = 1\relax\else\add@space\fi%
    \def@xxx\@thestring{\expandafter\expandafter\expandafter\@thestring%
      \csname arg\romannumeral\value{word@count}\endcsname}%
  }%
  \let~\SaveHardspace%
  \@thestring%
  \restore@sizes%
\un@define}

\newcommand\notitle@word[1]{%
  \def\symbol@flag{F}%
  \def@xx\the@string{#1}%
  \def\@thestring{}\def\make@cap{F}%
  \expandafter\eat@noTitleWord\the@string\string@end%
}

\def\eat@noTitleWord{\def\make@cap{F}\IfNextToken\string@end%
  {\@gobble}%
  {\title@string{\eat@noTitleWord}}%
}

\newcommand\title@word[1]{%
  \def\symbol@flag{F}%
  \def@xx\the@string{#1}%
  \def\@thestring{}\def\make@cap{T}%
  \expandafter\eat@TitleWord\the@string\string@end%
}


\def\eat@TitleWord{\IfNextToken\string@end%
  {\@gobble}%
  {\title@string{\eat@TitleWord}}%
}

\def\@symboli{\`}
\def\@symbolii{\'}
\def\@symboliii{\^}
\def\@symboliv{\"}
\def\@symbolv{\~}
\def\@symbolvi{\=}
\def\@symbolvii{\.}
\def\@symbolviii{\u}
\def\@symbolix{\v}
\def\@symbolx{\H}
\def\@symbolxi{\t}
\def\@symbolxii{\c}
\def\@symbolxiii{\d}
\def\@symbolxiv{\b}
\def\@symbolxv{\oe}
 \def\uc@symbolxv{\OE}
\def\@symbolxvi{\ae}
 \def\uc@symbolxvi{\AE}
\def\@symbolxvii{\o}
 \def\uc@symbolxvii{\O}
%\def\@symbolxviii{\aa}
% \def\uc@symbolxviii{\AA}
%\def\@symbolxix{\l}
% \def\uc@symbolxix{\L}
\newcounter{dia@count}

\def\title@string#1#2{%
  \if T\make@cap%
    \setcounter{dia@count}{1}%
    \if F\symbol@flag%
      \whiledo{\value{dia@count} < 18}{%
        \expandafter\expandafter\expandafter\ifx
           \csname @symbol\romannumeral\value{dia@count}\endcsname#2%
%BEGIN IFDIACRIT
          \ifnum\value{dia@count} < 15\relax%
%IF = DIACRIT<15
            \def@xx\di@critic%
              {\csname @symbol\romannumeral\value{dia@count}\endcsname}%
            \def\symbol@flag{D}%
            \setcounter{dia@count}{99}% INDICATING DICRIT JUST FOUND
           \else%
%IF = NATSYM
            \def@xx\di@critic%
              {\csname uc@symbol\romannumeral\value{dia@count}\endcsname}%
            \setcounter{dia@count}{90}% >19 AND <99 MEANS NON-DIACRIT SYMBOL
            \def\symbol@flag{N}%
           \fi%
         \else
%END IF = DIACRIT
%IFNOT = DIACRIT
          \addtocounter{dia@count}{1}\fi
      }% END WHILEDO
    \fi%
    \ifnum\value{dia@count} < 99\relax
      \if D\symbol@flag% FOR DIACRIT, ONCE ARGUMENT IS IN #2, TO BE CAPPED
        \def\next@char{\di@critic#2}%
        \def\symbol@flag{F}%
      \else%
        \if N\symbol@flag% FOR NATSYM TO BE CAPITALIZED
          \def\next@char{\di@critic}%
          \def\symbol@flag{F}%
        \else% FOR ANY OTHER CHARACTER TO BE CAPITALIZED
          \def\next@char{#2}%
        \fi%
      \fi%
      \expandafter\ifx\cmd@flag#2\relax\def\make@cap{T}\else%
        \def@xx\@thestring{\expandafter\@thestring\expandafter
          \uppercase\expandafter{\next@char}}%
        \def\make@cap{F}%
        \@checkfornewgroup{#2}%
      \fi
    \fi%
  \else% FOR CHARACTERS NOT TO BE CAPITALIZED
    \expandafter\ifx\cmd@flag#2
      \def\make@cap{T}%
    \else
      \def@x\@thestring{\@thestring#2}%
      \@checkfornewgroup{#2}%
    \fi
  \fi%
  #1}

\def\@checkfornewgroup#1{%
  \ifx-#1\def\make@cap{T}\else
    \ifx(#1\def\make@cap{T}\else
      \ifx[#1\def\make@cap{T}\else
        \ifx\{#1\def\make@cap{T}\else
          \ifx`#1\def\make@cap{T}\fi
        \fi
      \fi
    \fi
  \fi
}

%%%%%%%%%%%%%%%%%%
% DAVID CARLISLE GREATLY ASSISTED WITH THE \get@argsC COMMAND LOGIC

\def\string@@@end{$\SaveHardspace}
\def\converttilde{F}
\newcounter{arg@@@index}
\let\SaveHardspace~%%%
\def\the@@@rule{\rule{.8ex}{1.6ex}}%

\def\get@argsC#1{%
  \if T\converttilde\def~{ }\else\catcode`~=12 \fi
  \protected@edef\the@@@string{#1}%
  \setcounter{arg@@@index}{0}%
  \lowercase{\expandafter\parse@@@Block\the@@@string} \string@@@end
  \let~\SaveHardspace%
  \catcode`~=13 %
}

\def\parse@@@Block#1 {%
  \stepcounter{arg@@@index}%
  \@namedef{arg\romannumeral\value{arg@@@index}}{#1}%
  \ifthenelse{\equal{\argi}{}}{\addtocounter{arg@@@index}{-1}}{}%
  \futurelet\tmp\parse@@@Block@@@}

\def\parse@@@Block@@@{%
\ifx\tmp\string@@@end\edef\narg{\thearg@@@index}\expandafter\@gobble%
\else\expandafter\parse@@@Block\fi}

%%%%%%%%%%%%

\let\sv@tiny\tiny
\let\sv@scriptsize\scriptsize
\let\sv@footnotesize\footnotesize
\let\sv@small\small
\let\sv@normalsize\normalsize
\let\sv@large\large
\let\sv@Large\Large
\let\sv@LARGE\LARGE
\let\sv@huge\huge
\let\sv@huge\Huge

\let\make@lttr\makeatletter%
\let\make@othr\makeatother%

\newcommand\noatinsidetc{%
  \def\make@lttr{}%
  \def\make@othr{}%
}

\def\restore@sizes{%
  \let\tiny\sv@tiny%
  \let\scriptsize\sv@scriptsize%
  \let\footnotesize\sv@footnotesize%
  \let\small\sv@small%
  \let\normalsize\sv@normalsize%
  \let\large\sv@large%
  \let\Large\sv@Large%
  \let\LARGE\sv@LARGE%
  \let\huge\sv@huge%
  \let\huge\sv@Huge%
  \make@othr%
}

% THE \makeatletter IS REQUIRED FOR PROCESSING FONTSIZE CHANGES
\def\digest@sizes{%
\make@lttr%
\def\tiny{\unskip\sz@tiny\SoftSpace}%
\def\sz@tiny{\sv@tiny}%
%
\def\scriptsize{\unskip\sz@scriptsize\SoftSpace}%
\def\sz@scriptsize{\sv@scriptsize}%
%
\def\footnotesize{\unskip\sz@footnotesize\SoftSpace}%
\def\sz@footnotesize{\sv@footnotesize}%
%
\def\small{\unskip\sz@small\SoftSpace}%
\def\sz@small{\sv@small}%
%
\def\normalsize{\unskip\sz@normalsize\SoftSpace}%
\def\sz@normalsize{\sv@normalsize}%
%
\def\large{\unskip\sz@large\SoftSpace}%
\def\sz@large{\sv@large}%
%
\def\Large{\unskip\sz@Large\SoftSpace}%
\def\sz@Large{\sv@Large}%
%
\def\LARGE{\unskip\sz@LARGE\SoftSpace}%
\def\sz@LARGE{\sv@LARGE}%
%
\def\huge{\unskip\sz@huge\SoftSpace}%
\def\sz@huge{\sv@huge}%
%
\def\Huge{\unskip\sz@Huge\SoftSpace}%
\def\sz@Huge{\sv@Huge}%
}

\endinput