% \iffalse meta-comment
%
%% File: l3text-purify.dtx
%
% Copyright (C) 2020-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
% This file is part of the "l3kernel bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/latex3/latex3
%
% for those people who are interested.
%
%<*driver>
\documentclass[full,kernel]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3text-purify} module\\ Text processing (purification)^^A
% }
%
% \author{^^A
%  The \LaTeX{} Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released 2025-09-02}
%
% \maketitle
%
% \begin{documentation}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3text-purify} implementation}
%
%    \begin{macrocode}
%<*code>
%    \end{macrocode}
%
%    \begin{macrocode}
%<@@=text>
%    \end{macrocode}
%
% \subsection{Purifying text}
%
% \begin{macro}[EXP]{\@@_if_recursion_tail_stop:N}
%   Functions to query recursion quarks.
%    \begin{macrocode}
\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:N
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\text_purify:n, \@@_purify:n}
% \begin{macro}[EXP]{\@@_purify_store:n}
% \begin{macro}[EXP]{\@@_purify_store:nw}
% \begin{macro}[EXP]{\@@_purify_end:w}
% \begin{macro}[EXP]{\@@_purify_loop:w}
% \begin{macro}[EXP]{\@@_purify_group:n}
% \begin{macro}[EXP]{\@@_purify_space:w}
% \begin{macro}[EXP]{\@@_purify_N_type:N, \@@_purify_N_type_aux:N}
% \begin{macro}[EXP]{\@@_purify_math_search:NNN}
% \begin{macro}[EXP]{\@@_purify_math_start:NNw}
% \begin{macro}[EXP]{\@@_purify_math_store:n}
% \begin{macro}[EXP]{\@@_purify_math_store:nw}
% \begin{macro}[EXP]{\@@_purify_math_end:w}
% \begin{macro}[EXP]{\@@_purify_math_loop:NNw}
% \begin{macro}[EXP]{\@@_purify_math_N_type:NNN}
% \begin{macro}[EXP]{\@@_purify_math_group:NNn}
% \begin{macro}[EXP]{\@@_purify_math_space:NNw}
% \begin{macro}[EXP]{\@@_purify_math_cmd:N}
% \begin{macro}[EXP]{\@@_purify_math_cmd:NN}
% \begin{macro}[EXP]{\@@_purify_math_cmd:Nn}
% \begin{macro}[EXP]{\@@_purify_replace:N}
% \begin{macro}[EXP]{\@@_purify_replace_auxi:n, \@@_purify_replace_auxii:n}
% \begin{macro}[EXP]{\@@_purify_expand:N, \@@_purify_protect:N, \@@_purify_encoding:N}
% \begin{macro}[EXP]{\@@_purify_encoding_escape:NN}
%   As in the other parts of the module, we start off with a standard
%   \enquote{action} loop, with expansion applied up-front.
%    \begin{macrocode}
\cs_new:Npn \text_purify:n #1
  {
    \__kernel_exp_not:w \exp_after:wN
      {
        \exp:w
        \exp_args:Ne \@@_purify:n
          { \text_expand:n {#1} }
      }
  }
\cs_new:Npn \@@_purify:n #1
  {
    \group_align_safe_begin:
    \@@_purify_loop:w #1
      \q_@@_recursion_tail \q_@@_recursion_stop
    \@@_purify_result:n { }
  }
%    \end{macrocode}
%   As for expansion, collect up the tokens for future use.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_store:n #1
  { \@@_purify_store:nw {#1} }
\cs_new:Npn \@@_purify_store:nw #1#2 \@@_purify_result:n #3
  { #2 \@@_purify_result:n { #3 #1 } }
\cs_new:Npn \@@_purify_end:w #1 \@@_purify_result:n #2
  {
    \group_align_safe_end:
    \exp_end:
    #2
  }
%    \end{macrocode}
%   The main loop is a standard \enquote{tl action}. Unlike the expansion
%   or case changing, here any groups have to be run inline. Most of the
%   business end is as before in the \texttt{N}-type token processing.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_loop:w #1 \q_@@_recursion_stop
  {
    \tl_if_head_is_N_type:nTF {#1}
      { \@@_purify_N_type:N }
      {
        \tl_if_head_is_group:nTF {#1}
          { \@@_purify_group:n }
          { \@@_purify_space:w }
      }
    #1 \q_@@_recursion_stop
  }
\cs_new:Npn \@@_purify_group:n #1 { \@@_purify_loop:w #1 }
\exp_last_unbraced:NNo \cs_new:Npn \@@_purify_space:w \c_space_tl
  {
    \@@_purify_store:n { ~ }
    \@@_purify_loop:w
  }
%    \end{macrocode}
%   The first part of handling math mode is exactly the same as in the
%   other functions: look for a start-of-math mode token and if found start
%   a new loop tracking the closing token.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_N_type:N #1
  {
    \@@_if_q_recursion_tail_stop_do:Nn #1 { \@@_purify_end:w }
    \@@_purify_N_type_aux:N #1
  }
\cs_new:Npn \@@_purify_N_type_aux:N #1
  {
    \exp_after:wN \@@_purify_math_search:NNN
      \exp_after:wN #1 \l_text_math_delims_tl
      \q_@@_recursion_tail ?
      \q_@@_recursion_stop
  }
\cs_new:Npn \@@_purify_math_search:NNN #1#2#3
  {
    \@@_if_q_recursion_tail_stop_do:Nn #2
      { \@@_purify_math_cmd:N #1 }
    \token_if_eq_meaning:NNTF #1 #2
      {
        \@@_use_i_delimit_by_q_recursion_stop:nw
          { \@@_purify_math_start:NNw #2 #3 }
      }
      { \@@_purify_math_search:NNN #1 }
  }
\cs_new:Npn \@@_purify_math_start:NNw #1#2#3 \q_@@_recursion_stop
  {
    \@@_purify_math_loop:NNw #1#2#3 \q_@@_recursion_stop
      \@@_purify_math_result:n { }
  }
\cs_new:Npn \@@_purify_math_store:n #1
  { \@@_purify_math_store:nw {#1} }
\cs_new:Npn \@@_purify_math_store:nw #1#2 \@@_purify_math_result:n #3
  { #2 \@@_purify_math_result:n { #3 #1 } }
\cs_new:Npn \@@_purify_math_end:w #1 \@@_purify_math_result:n #2
  {
    \@@_purify_store:n { $ #2 $ }
    \@@_purify_loop:w #1
  }
\cs_new:Npn \@@_purify_math_stop:Nw #1 \@@_purify_math_result:n #2
  {
    \@@_purify_store:n {#1#2}
    \@@_purify_end:w
  }
\cs_new:Npn \@@_purify_math_loop:NNw #1#2#3 \q_@@_recursion_stop
  {
    \tl_if_head_is_N_type:nTF {#3}
      { \@@_purify_math_N_type:NNN }
      {
        \tl_if_head_is_group:nTF {#3}
          { \@@_purify_math_group:NNn }
          { \@@_purify_math_space:NNw }
      }
        #1#2#3 \q_@@_recursion_stop
  }
\cs_new:Npn \@@_purify_math_N_type:NNN #1#2#3
  {
    \@@_if_q_recursion_tail_stop_do:Nn #3
      { \@@_purify_math_stop:Nw #1 }
    \token_if_eq_meaning:NNTF #3 #2
      { \@@_purify_math_end:w }
      {
        \@@_purify_math_store:n {#3}
        \@@_purify_math_loop:NNw #1#2
      }
  }
\cs_new:Npn \@@_purify_math_group:NNn #1#2#3
  {
    \@@_purify_math_store:n { {#3} }
    \@@_purify_math_loop:NNw #1#2
  }
\exp_after:wN \cs_new:Npn \exp_after:wN \@@_purify_math_space:NNw 
  \exp_after:wN # \exp_after:wN 1
  \exp_after:wN # \exp_after:wN 2 \c_space_tl
  {
    \@@_purify_math_store:n { ~ }
    \@@_purify_math_loop:NNw #1#2
  }
%    \end{macrocode}
%   Then handle math mode as an argument: same outcomes, different input
%   syntax.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_math_cmd:N #1
  {
    \exp_after:wN \@@_purify_math_cmd:NN \exp_after:wN #1
      \l_text_math_arg_tl \q_@@_recursion_tail \q_@@_recursion_stop
  }
\cs_new:Npn \@@_purify_math_cmd:NN #1#2
  {
    \@@_if_q_recursion_tail_stop_do:Nn #2
      { \@@_purify_replace:N #1 }
    \cs_if_eq:NNTF #2 #1
      {
        \@@_use_i_delimit_by_q_recursion_stop:nw
          { \@@_purify_math_cmd:n }
      }
      { \@@_purify_math_cmd:NN #1 }
  }
\cs_new:Npn \@@_purify_math_cmd:n #1
  { \@@_purify_math_end:w \@@_purify_math_result:n {#1} }
%    \end{macrocode}
%   For \texttt{N}-type tokens, we first look for a string-context replacement
%   before anything else: this can therefore cover anything. Assuming we don't
%   find one, check to see if we can expand control sequences: if not, they have
%   to be dropped. We also allow for \LaTeXe{} \tn{protect}: there's an
%   assumption that we don't have |\protect { \oops }| or similar, but that's
%   also in the expansion code and seems like a reasonable balance. Notice that
%   we filter out implicit begin/end group tokens to avoid issues.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_replace:N #1
  {
    \bool_lazy_and:nnTF
      { \cs_if_exist_p:c { l_@@_purify_ \token_to_str:N #1 _tl } }
      {
        \bool_lazy_or_p:nn
          { \token_if_cs_p:N #1 }
          { \token_if_active_p:N #1 }
      }
      {
        \exp_args:Nv \@@_purify_replace_auxi:n
          { l_@@_purify_ \token_to_str:N #1 _tl }
      }
      {
        \bool_lazy_or:nnTF
          { \token_if_group_begin_p:N #1 }
          { \token_if_group_end_p:N #1 }
          { \@@_purify_loop:w }
          {
            \exp_args:Ne \@@_purify_replace_auxii:n
              { \@@_token_to_explicit:N #1 }
          }
      }
  }
\cs_new:Npn \@@_purify_replace_auxi:n #1 { \@@_purify_loop:w #1 }
\cs_new:Npn \@@_purify_replace_auxii:n #1
  {
    \token_if_cs:NTF #1
      { \@@_purify_expand:N #1 }
      {
        \@@_purify_store:n {#1}
        \@@_purify_loop:w
      }
  }
\cs_new:Npn \@@_purify_expand:N #1
  {
    \str_if_eq:nnTF {#1} { \protect }
      { \@@_purify_protect:N }
      { \@@_purify_encoding:N #1 }
  }
\cs_new:Npn \@@_purify_protect:N #1
  {
    \@@_if_q_recursion_tail_stop_do:Nn #1 { \@@_purify_end:w }
    \@@_purify_loop:w
  }
%    \end{macrocode}
%   Handle encoding commands, as detailed for expansion.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_encoding:N #1
  {
    \bool_lazy_or:nnTF
      { \cs_if_eq_p:NN #1 \@current@cmd }
      { \cs_if_eq_p:NN #1 \@changed@cmd }
      { \@@_purify_encoding_escape:NN }
      {
        \@@_if_expandable:NTF #1
          { \exp_after:wN \@@_purify_loop:w #1 }
          { \@@_purify_loop:w }
      }
  }
\cs_new:Npn \@@_purify_encoding_escape:NN #1#2
  {
    \@@_purify_store:n {#1}
    \@@_purify_loop:w
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}
%   {
%     \text_declare_purify_equivalent:Nn,
%     \text_declare_purify_equivalent:Ne
%   }
%    \begin{macrocode}
\cs_new_protected:Npn \text_declare_purify_equivalent:Nn #1#2
  {
    \tl_clear_new:c { l_@@_purify_ \token_to_str:N #1 _tl }
    \tl_set:cn { l_@@_purify_ \token_to_str:N #1 _tl } {#2}
  }
\cs_generate_variant:Nn \text_declare_purify_equivalent:Nn { Ne }
%    \end{macrocode}
% \end{macro}
%
% Now pre-define a range of standard commands that need dedicated definitions
% in purified text. First handle font-related stuff: all of this needs to be
% disabled.
%    \begin{macrocode}
\tl_map_inline:nn
  {
    \fontencoding
    \fontfamily
    \fontseries
    \fontshape
  }
  { \text_declare_purify_equivalent:Nn #1 { \use_none:n } }
\text_declare_purify_equivalent:Nn \fontsize { \use_none:nn }
\text_declare_purify_equivalent:Nn \selectfont { }
\text_declare_purify_equivalent:Nn \usefont { \use_none:nnnn }
\exp_args:Nc \text_declare_purify_equivalent:Nn
  { @protected@testopt } { \use_none:nnn }
%    \end{macrocode}
% Environments have to be handled by pure expansion.
%
% \begin{macro}{\@@_end_env:n}
%    \begin{macrocode}
\text_declare_purify_equivalent:Nn \begin { \use:c }
\text_declare_purify_equivalent:Nn \end { \@@_end_env:n }
\cs_new:Npn \@@_end_env:n #1 { \cs:w end #1 \cs_end: }
%    \end{macrocode}
% \end{macro}
%
% Some common symbols and similar ideas.
%    \begin{macrocode}
\text_declare_purify_equivalent:Nn \\ { }
\tl_map_inline:nn
  { \{ \} \# \$ \% \_ }
  { \text_declare_purify_equivalent:Ne #1 { \cs_to_str:N #1 } }
%    \end{macrocode}
% Cross-referencing.
%    \begin{macrocode}
\text_declare_purify_equivalent:Nn \label { \use_none:n }
%    \end{macrocode}
% Spaces.
%    \begin{macrocode}
\group_begin:
\char_set_catcode_active:N \~
\use:n
  {
    \group_end:
    \text_declare_purify_equivalent:Ne ~ { \c_space_tl }
  }
\text_declare_purify_equivalent:Nn \nobreakspace { ~ }
\text_declare_purify_equivalent:Nn \  { ~ }
\text_declare_purify_equivalent:Nn \, { ~ }
%    \end{macrocode}
%
% \subsection{Accent and letter-like data for purifying text}
%
% In contrast to case changing, both $8$-bit and Unicode engines need
% information for text purification to handle accents and letter-like
% functions: these all need to be removed. However, the results are
% of course engine-dependent.
%
% For the letter-like commands, life is relatively easy: they are all
% simply added as standard exceptions. The only oddity is \tn{SS}, which
% gets converted to two letters. (At some stage an alternative version
% can presumably be added to \pkg{babel} or similar.)
%    \begin{macrocode}
\cs_set_protected:Npn \@@_loop:Nn #1#2
  {
    \quark_if_recursion_tail_stop:N #1
    \text_declare_purify_equivalent:Ne #1
      {
        \codepoint_generate:nn {"#2}
          { \char_value_catcode:n {"#2} }
      }
    \@@_loop:Nn
  }
\@@_loop:Nn
  \AA { 00C5 }
  \AE { 00C6 }
  \DH { 00D0 }
  \DJ { 0110 }
  \IJ { 0132 }
  \L  { 0141 }
  \NG { 014A }
  \O  { 00D8 }
  \OE { 0152 }
  \TH { 00DE }
  \aa { 00E5 }
  \ae { 00E6 }
  \dh { 00F0 }
  \dj { 0111 }
  \i  { 0131 }
  \j  { 0237 }
  \ij { 0132 }
  \l  { 0142 }
  \ng { 014B }
  \o  { 00F8 }
  \oe { 0153 }
  \ss { 00DF }
  \th { 00FE }
  \q_recursion_tail ?
  \q_recursion_stop
\text_declare_purify_equivalent:Nn \SS { SS }
%    \end{macrocode}
%
% \begin{macro}[rEXP]{\@@_purify_accent:NN}
%   Accent \textsc{licr} handling is a little more complex. Accents may exist
%   as pre-composed codepoints or as independent glyphs. The former are all
%   saved as single token lists, whilst for the latter the combining accent
%   needs to be re-ordered compared to the character it applies to.
%    \begin{macrocode}
\cs_new:Npn \@@_purify_accent:NN #1#2
  {
    \cs_if_exist:cTF
      { c_@@_purify_ \token_to_str:N #1 _ \token_to_str:N #2 _tl }
      {
        \exp_not:v
          { c_@@_purify_ \token_to_str:N #1 _ \token_to_str:N #2 _tl }
      }
      {
        \exp_not:n {#2}
        \exp_not:v { c_@@_purify_ \token_to_str:N #1 _tl }
      }
  }
\tl_map_inline:nn { \` \' \^ \~ \= \u \. \" \r \H \v \d \c \k \b \t }
  { \text_declare_purify_equivalent:Nn #1 { \@@_purify_accent:NN #1 } }
%    \end{macrocode}
%   First set up the combining accents.
%    \begin{macrocode}
\group_begin:
  \cs_set_protected:Npn \@@_loop:Nn #1#2
    {
      \quark_if_recursion_tail_stop:N #1
      \tl_const:ce { c_@@_purify_ \token_to_str:N #1 _tl }
        { \codepoint_generate:nn {"#2} { \char_value_catcode:n { "#2 } } }
      \@@_loop:Nn
    }
  \@@_loop:Nn
    \` { 0300 }
    \' { 0301 }
    \^ { 0302 }
    \~ { 0303 }
    \= { 0304 }
    \u { 0306 }
    \. { 0307 }
    \" { 0308 }
    \r { 030A }
    \H { 030B }
    \v { 030C }
    \d { 0323 }
    \c { 0327 }
    \k { 0328 }
    \b { 0331 }
    \t { 0361 }
    \q_recursion_tail { }
    \q_recursion_stop
%    \end{macrocode}
%   Now we handle the pre-composed accents: the list here is taken from
%   \texttt{puenc.def}. All of the precomposed cases take a single letter
%   as their second argument. We do not try to cover the case where an accent
%   is added to a \enquote{real} dotless-i or -j, or a \ae/\AE. Rather, we
%   assume that if the \textsc{utf}-8 character is used, it will have the
%   real accent character too.
%    \begin{macrocode}
  \cs_set_protected:Npn \@@_loop:NNn #1#2#3
    {
      \quark_if_recursion_tail_stop:N #1
      \tl_const:ce
        { c_@@_purify_ \token_to_str:N #1 _ \token_to_str:N #2 _tl }
        { \codepoint_generate:nn {"#3} { \char_value_catcode:n { "#3 } } }
      \@@_loop:NNn
    }
  \@@_loop:NNn
    \` A   { 00C0 }
    \' A   { 00C1 }
    \^ A   { 00C2 }
    \~ A   { 00C3 }
    \" A   { 00C4 }
    \r A   { 00C5 }
    \c C   { 00C7 }
    \` E   { 00C8 }
    \' E   { 00C9 }
    \^ E   { 00CA }
    \" E   { 00CB }
    \` I   { 00CC }
    \' I   { 00CD }
    \^ I   { 00CE }
    \" I   { 00CF }
    \~ N   { 00D1 }
    \` O   { 00D2 }
    \' O   { 00D3 }
    \^ O   { 00D4 }
    \~ O   { 00D5 }
    \" O   { 00D6 }
    \` U   { 00D9 }
    \' U   { 00DA }
    \^ U   { 00DB }
    \" U   { 00DC }
    \' Y   { 00DD }
    \` a   { 00E0 }
    \' a   { 00E1 }
    \^ a   { 00E2 }
    \~ a   { 00E3 }
    \" a   { 00E4 }
    \r a   { 00E5 }
    \c c   { 00E7 }
    \` e   { 00E8 }
    \' e   { 00E9 }
    \^ e   { 00EA }
    \" e   { 00EB }
    \` i   { 00EC }
    \` \i  { 00EC }
    \' i   { 00ED }
    \' \i  { 00ED }
    \^ i   { 00EE }
    \^ \i  { 00EE }
    \" i   { 00EF }
    \" \i  { 00EF }
    \~ n   { 00F1 }
    \` o   { 00F2 }
    \' o   { 00F3 }
    \^ o   { 00F4 }
    \~ o   { 00F5 }
    \" o   { 00F6 }
    \` u   { 00F9 }
    \' u   { 00FA }
    \^ u   { 00FB }
    \" u   { 00FC }
    \' y   { 00FD }
    \" y   { 00FF }
    \= A   { 0100 }
    \= a   { 0101 }
    \u A   { 0102 }
    \u a   { 0103 }
    \k A   { 0104 }
    \k a   { 0105 }
    \' C   { 0106 }
    \' c   { 0107 }
    \^ C   { 0108 }
    \^ c   { 0109 }
    \. C   { 010A }
    \. c   { 010B }
    \v C   { 010C }
    \v c   { 010D }
    \v D   { 010E }
    \v d   { 010F }
    \= E   { 0112 }
    \= e   { 0113 }
    \u E   { 0114 }
    \u e   { 0115 }
    \. E   { 0116 }
    \. e   { 0117 }
    \k E   { 0118 }
    \k e   { 0119 }
    \v E   { 011A }
    \v e   { 011B }
    \^ G   { 011C }
    \^ g   { 011D }
    \u G   { 011E }
    \u g   { 011F }
    \. G   { 0120 }
    \. g   { 0121 }
    \c G   { 0122 }
    \c g   { 0123 }
    \^ H   { 0124 }
    \^ h   { 0125 }
    \~ I   { 0128 }
    \~ i   { 0129 }
    \~ \i  { 0129 }
    \= I   { 012A }
    \= i   { 012B }
    \= \i  { 012B }
    \u I   { 012C }
    \u i   { 012D }
    \u \i  { 012D }
    \k I   { 012E }
    \k i   { 012F }
    \k \i  { 012F }
    \. I   { 0130 }
    \^ J   { 0134 }
    \^ j   { 0135 }
    \^ \j  { 0135 }
    \c K   { 0136 }
    \c k   { 0137 }
    \' L   { 0139 }
    \' l   { 013A }
    \c L   { 013B }
    \c l   { 013C }
    \v L   { 013D }
    \v l   { 013E }
    \. L   { 013F }
    \. l   { 0140 }
    \' N   { 0143 }
    \' n   { 0144 }
    \c N   { 0145 }
    \c n   { 0146 }
    \v N   { 0147 }
    \v n   { 0148 }
    \= O   { 014C }
    \= o   { 014D }
    \u O   { 014E }
    \u o   { 014F }
    \H O   { 0150 }
    \H o   { 0151 }
    \' R   { 0154 }
    \' r   { 0155 }
    \c R   { 0156 }
    \c r   { 0157 }
    \v R   { 0158 }
    \v r   { 0159 }
    \' S   { 015A }
    \' s   { 015B }
    \^ S   { 015C }
    \^ s   { 015D }
    \c S   { 015E }
    \c s   { 015F }
    \v S   { 0160 }
    \v s   { 0161 }
    \c T   { 0162 }
    \c t   { 0163 }
    \v T   { 0164 }
    \v t   { 0165 }
    \~ U   { 0168 }
    \~ u   { 0169 }
    \= U   { 016A }
    \= u   { 016B }
    \u U   { 016C }
    \u u   { 016D }
    \r U   { 016E }
    \r u   { 016F }
    \H U   { 0170 }
    \H u   { 0171 }
    \k U   { 0172 }
    \k u   { 0173 }
    \^ W   { 0174 }
    \^ w   { 0175 }
    \^ Y   { 0176 }
    \^ y   { 0177 }
    \" Y   { 0178 }
    \' Z   { 0179 }
    \' z   { 017A }
    \. Z   { 017B }
    \. z   { 017C }
    \v Z   { 017D }
    \v z   { 017E }
    \v A   { 01CD }
    \v a   { 01CE }
    \v I   { 01CF }
    \v \i  { 01D0 }
    \v i   { 01D0 }
    \v O   { 01D1 }
    \v o   { 01D2 }
    \v U   { 01D3 }
    \v u   { 01D4 }
    \v G   { 01E6 }
    \v g   { 01E7 }
    \v K   { 01E8 }
    \v k   { 01E9 }
    \k O   { 01EA }
    \k o   { 01EB }
    \v \j  { 01F0 }
    \v j   { 01F0 }
    \' G   { 01F4 }
    \' g   { 01F5 }
    \` N   { 01F8 }
    \` n   { 01F9 }
    \' \AE { 01FC }
    \' \ae { 01FD }
    \' \O  { 01FE }
    \' \o  { 01FF }
    \v H   { 021E }
    \v h   { 021F }
    \. A   { 0226 }
    \. a   { 0227 }
    \c E   { 0228 }
    \c e   { 0229 }
    \. O   { 022E }
    \. o   { 022F }
    \= Y   { 0232 }
    \= y   { 0233 }
    \q_recursion_tail ? { }
    \q_recursion_stop
\group_end:
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</code>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
