% -*- coding: utf-8 -*-
% !TEX program = lualatex
\documentclass[oneside]{book}
\usepackage[a4paper,margin=2.5cm]{geometry}

\newcommand*{\myversion}{2024C}
\newcommand*{\mydate}{Version \myversion\ (\the\year-\mylpad\month-\mylpad\day)}
\newcommand*{\mylpad}[1]{\ifnum#1<10 0\the#1\else\the#1\fi}

\setlength{\parindent}{0pt}
\setlength{\parskip}{4pt plus 1pt minus 1pt}

\usepackage{codehigh}

\colorlet{highback}{blue9}
%\CodeHigh{lite}
\CodeHigh{language=latex/latex2,style/main=highback,style/code=highback}
\NewCodeHighEnv{code}{style/main=gray9,style/code=gray9}
\NewCodeHighEnv{demo}{style/main=gray9,style/code=gray9,demo}

\usepackage{enumitem}

\NewDocumentCommand\MySubScript{m}{$_{#1}$}

\ExplSyntaxOn
\NewDocumentCommand\PrintVarList{m}{
  \clist_set:Nn \l_tmpa_clist {#1}
  \clist_map_inline:Nn \l_tmpa_clist
    {
      \token_to_str:N ##1 ~
    }
}
\NewDocumentCommand\RelaceChacters{m}{
  \tl_set:Nn \lTmpaTl {#1}
  \regex_replace_once:nnN { \_ } { \c{MySubScript} } \lTmpaTl
}
\NewDocumentCommand\RelaceUnderScoreAll{m}{
  \tl_set:Nn \lTmpaTl {#1}
  \regex_replace_all:nnN { \_ } { \c{_} } \lTmpaTl
  \lTmpaTl
}
\ExplSyntaxOff

\NewDocumentEnvironment{variable}{om}{
  \vspace{5pt}
  \begin{minipage}{\linewidth}
  \hrule\vspace{4pt}\obeylines%
  \begingroup
  \ttfamily\bfseries\color{azure3}
  \PrintVarList{#2}
  \endgroup
  \par\vspace{4pt}\hrule
  \end{minipage}\par\nopagebreak\vspace{4pt}
}{%
  \vspace{5pt}%
}

\NewDocumentEnvironment{function}{om}{
  \vspace{5pt}%
}{\vspace{5pt}}

\NewDocumentEnvironment{syntax}{}{%
  \begin{minipage}{\linewidth}
  \hrule\vspace{4pt}\obeylines%
}{%
  \par\vspace{4pt}\hrule
  \end{minipage}\par\nopagebreak\vspace{4pt}
}

\NewDocumentEnvironment{texnote}{}{}{}

\NewDocumentCommand\cs{O{}m}{%
  \texttt{\bfseries\color{purple3}\cBackslashStr\RelaceUnderScoreAll{#2}}%
}
\NewDocumentCommand\meta{m}{%
  \RelaceChacters{#1}%
  \textsl{$\langle$\ignorespaces\lTmpaTl\unskip$\rangle$}%
}
\NewDocumentCommand\Arg{m}{%
  \RelaceChacters{#1}%
  \texttt{\{}\textsl{$\langle$\ignorespaces\lTmpaTl\unskip$\rangle$}\texttt{\}}%
}

\NewDocumentCommand\pkg{m}{\textsf{#1}}

\NewDocumentCommand\nan{}{\texttt{NaN}}
\NewDocumentCommand\enquote{m}{``#1''}

\let\tn=\cs

\RenewDocumentCommand\emph{m}{%
  \underline{\textsl{#1}}%
}

\newenvironment{l3regex-syntax}
  {\begin{itemize}\def\\{\char`\\}\def\makelabel##1{\hss\llap{\ttfamily##1}}}
  {\end{itemize}}

\usepackage{shortvrb}

\NewDocumentCommand \MyMakeShortVerb {} {%
  \MakeShortVerb \|%
  \MakeShortVerb \"%
}
\NewDocumentCommand \MyDeleteShortVerb {} {%
  \DeleteShortVerb \|%
  \DeleteShortVerb \"%
}

\AtBeginDocument{\MyMakeShortVerb}
\AtEndDocument{\MyDeleteShortVerb}
\AddToHook{env/demohigh/before}{\MyDeleteShortVerb}
\AddToHook{env/demohigh/after}{\MyMakeShortVerb}

\usepackage{hologo}
\providecommand*\LuaTeX{\hologo{LuaTeX}}
\providecommand*\pdfTeX{\hologo{pdfTeX}}
\providecommand*\XeTeX{\hologo{XeTeX}}

\usepackage{amsmath}

\usepackage{hyperref}
\hypersetup{
  colorlinks=true,
  urlcolor=blue3,
  linkcolor=blue3,
}

\makeatletter
\ExplSyntaxOn
\NewDocumentCommand\MyCheckLoadPackage{m}{
  \@ifpackageloaded{docmute}{
    \usepackage{#1}
  }{
    \str_if_eq:onTF{\jobname}{#1}{
      \usepackage{#1}
    }{
      \debug_on:n{check-declarations}
      \usepackage{#1}
      \debug_off:n{check-declarations}
    }
  }
}
\ExplSyntaxOff
\makeatother
\MyCheckLoadPackage{functional}
%\usepackage{functional}
%\Functional{scoping=false,tracing=true}

\begin{document}

\title{\sffamily Intuitive \textcolor{green3}{Functional} Programming Interface for LaTeX2}
\author{Jianrui Lyu (tolvjr@163.com)\\\url{https://github.com/lvjr/functional}}
\date{\mydate\vspace{1cm}\\\myabstract\vspace{10cm}}

\newcommand\myabstract{\parbox{\linewidth}{\hrule\vspace{0.8em}\large
This package provides an intuitive functional programming interface for LaTeX2,
which is an alternative choice to \textsf{expl3} or LuaTeX,
if you want to do programming in LaTeX.
\par\vspace{0.5em}
Although there are functions in LaTeX3 programming layer (\textsf{expl3}),
the evaluation of them is from outside to inside.
With this package, the evaluation of functions is from inside to outside,
which is the same as other programming languages such as \texttt{Lua}.
In this way, it is rather easy to debug code too.
\par\vspace{0.5em}
Note that many paragraphs in this manual are copied from the documentation of \textsf{expl3}.
\par\vspace{0.8em}\hrule}}

{\let\newpage\relax\vspace{-4cm}\maketitle}

\tableofcontents

\chapter{Overview of Features}

\section{Evaluation from Inside to Outside}

We will compare our first example with a similar \verb!Lua! example:

\begin{minipage}{0.55\textwidth}
\begin{codehigh}
\IgnoreSpacesOn
\prgNewFunction \mathSquare { m } {
  \intSet \lTmpaInt {\intEval {#1 * #1}}
  \prgReturn {\expValue \lTmpaInt}
}
\IgnoreSpacesOff
\mathSquare{5}
\mathSquare{\mathSquare{5}}
\end{codehigh}
\end{minipage}%
\begin{minipage}{0.45\textwidth}
\begin{code}
-- define a function --
function MathSquare (arg)
  local lTmpaInt = arg * arg
  return lTmpaInt
end
-- use the function --
print(MathSquare(5))
print(MathSquare(MathSquare(5)))
\end{code}
\end{minipage}

%\IgnoreSpacesOn
%\prgNewFunction \mathSquare { m }{
%  \intSet \lTmpaInt { \intEval { #1 * #1 } }
%  \prgReturn { \expValue \lTmpaInt }
%}
%\IgnoreSpacesOff
%\mathSquare{5}
%\mathSquare{\mathSquare{5}}

%\IgnoreSpacesOn
%\prgNewFunction \mathCubic { m }
%  {
%    \intSet \lTmpaInt { \intEval { #1 * #1 * #1 } }
%    \prgReturn { \expValue \lTmpaInt }
%  }
%\IgnoreSpacesOff
%\mathCubic{2}
%\mathCubic{\mathCubic{2}}

Both examples calculate first the square of $5$ and produce $25$,
then calculate the square of $25$ and produce $625$.
In contrast to \verb!expl3!, this \verb!functional! package
does evaluation of functions from inside to outside,
which means composition of functions works like other programming languages
such as \verb!Lua! or \verb!JavaScript!.

You can define new functions with \cs{prgNewFunction} command.
To make composition of functions work as expected,
every function \emph{must not} insert directly any token to the input stream.
Instead, a function \emph{must} pass the result (if any) to \verb!functional! package
with \cs{prgReturn} command. And \verb!functional! package is responsible for
inserting result tokens to the input stream at the appropriate time.

To remove space tokens inside function code in defining functions,
you'd better put function definitions inside \verb!\IgnoreSpacesOn! and
\verb!\IgnoreSpacesOff! block. Within this block, \verb!~! is used to input a space.

At the end of this section,
we will compare our factorial example with a similar \verb!Lua! example:

\begin{minipage}{0.68\textwidth}
\begin{codehigh}
\IgnoreSpacesOn
\prgNewFunction \mathFact { m } {
  \intCompareTF {#1} = {0} {
    \prgReturn {1}
  }{
    \prgReturn {\intEval{#1*\mathFact{\intEval{#1-1}}}}
  }
}
\IgnoreSpacesOff
\mathFact{4}
\end{codehigh}
\end{minipage}%
\begin{minipage}{0.32\textwidth}
\begin{code}
-- define a function --
function Fact (n)
  if n == 0 then
    return 1
  else
    return n * Fact(n-1)
  end
end
-- use the function --
print(Fact(4))
\end{code}
\end{minipage}

%\IgnoreSpacesOn
%\prgNewFunction \Factorial { m } {
%  \intCompareTF {#1} = {0} {
%    \prgReturn {1}
%  }{
%    \prgReturn { \intMathMult {#1} { \Factorial { \intMathSub{#1}{1} } } }
%  }
%}
%\IgnoreSpacesOff
%\Factorial{0}
%\Factorial{4}

\section{Group Scoping of Functions}

In \verb!Lua! language, a function or a condition expression makes a block,
and the values of local variables will be reset after a block.
In \verb!functional! package, a condition expression is in fact a function,
and you can make every function become a group by setting
\verb!\Functional{scoping=true}!. For example

\begin{minipage}{0.58\textwidth}
\begin{codehigh}
\Functional{scoping=true}
\IgnoreSpacesOn
\intSet \lTmpaInt {1}
\intVarLog \lTmpaInt            % ---- 1
\prgNewFunction \someFun { } {
  \intSet \lTmpaInt {2}
  \intVarLog \lTmpaInt          % ---- 2
  \intCompareTF {1} > {0} {
    \intSet \lTmpaInt {3}
    \intVarLog \lTmpaInt        % ---- 3
  }{ }
  \intVarLog \lTmpaInt          % ---- 2
}
\someFun
\intVarLog \lTmpaInt            % ---- 1
\IgnoreSpacesOff
\end{codehigh}
\end{minipage}%
\begin{minipage}{0.42\textwidth}
\begin{code}
-- lua code --
-- begin example --
local a = 1
print(a)            ---- 1
function SomeFun()
  local a = 2
  print(a)          ---- 2
  if 1 > 0 then
    local a = 3
    print(a)        ---- 3
  end
  print(a)          ---- 2
end
SomeFun()
print(a)            ---- 1
-- end example --
\end{code}
\end{minipage}

Same as \verb!expl3!, the names of local variables \emph{must} start with \verb!l!,
while names of global variables \emph{must} start with \verb!g!.
The difference is that \verb!functional! package provides only one function for setting
both local and global variables of the same type,
by checking leading letters of their names. So for integer variables, you can write
\verb!\intSet\lTmpaInt{1}! and \verb!\intSet\gTmpbInt{2}!.

The previous example will produce different result
if we change variable from \verb!\lTmpaInt! to \verb!\gTmpaInt!.

\begin{minipage}{0.58\textwidth}
\begin{codehigh}
\Functional{scoping=true}
\IgnoreSpacesOn
\intSet \gTmpaInt {1}
\intVarLog \gTmpaInt            % ---- 1
\prgNewFunction \someFun { } {
  \intSet \gTmpaInt {2}
  \intVarLog \gTmpaInt          % ---- 2
  \intCompareTF {1} > {0} {
    \intSet \gTmpaInt {3}
    \intVarLog \gTmpaInt        % ---- 3
  }{ }
  \intVarLog \gTmpaInt          % ---- 3
}
\someFun
\intVarLog \gTmpaInt            % ---- 3
\IgnoreSpacesOff
\end{codehigh}
\end{minipage}%
\begin{minipage}{0.42\textwidth}
\begin{code}
-- lua code --
-- begin example --
a = 1
print(a)            ---- 1
function SomeFun()
  a = 2
  print(a)          ---- 2
  if 1 > 0 then
    a = 3
    print(a)        ---- 3
  end
  print(a)          ---- 3
end
SomeFun()
print(a)            ---- 3
-- end example --
\end{code}
\end{minipage}

As you can see, the values of global variables will never be reset after a group.

\section{Tracing Evaluation of Functions}

Since every function in \verb!functional! package will pass its return value to
the package, it is quite easy to debug your code.
You can turn on the tracing by setting \verb!\Functional{tracing=true}!.
For example, the tracing log of the first example in this chapter will be the following:

% FIXME: spaces at the first line will be removed
%\begin{codehigh}[]
%    [I] \mathSquare{5}
%            [I] \intEval{5*5}
%                    [I] \expWhole{\int_eval:n {5*5}}
%                    [O] 25
%                [I] \prgReturn{25}
%                [O] 25
%            [O] 25
%        [I] \intSet\lTmpaInt {25}
%        [O]
%            [I] \expValue\lTmpaInt
%            [O] 25
%        [I] \prgReturn{25}
%        [O] 25
%    [O] 25
%\end{codehigh}
\begin{codehigh}[]
[I] \mathSquare{5}
        [I] \intEval{5*5}
                [I] \expWhole{\int_eval:n {5*5}}
                [O] 25
            [I] \prgReturn{25}
            [O] 25
        [O] 25
    [I] \intSet{\lTmpaInt }{25}
    [O]
        [I] \expValue{\lTmpaInt }
        [O] 25
    [I] \prgReturn{25}
    [O] 25
[O] 25
[I] \mathSquare{25}
        [I] \intEval{25*25}
                [I] \expWhole{\int_eval:n {25*25}}
                [O] 625
            [I] \prgReturn{625}
            [O] 625
        [O] 625
    [I] \intSet{\lTmpaInt }{625}
    [O]
        [I] \expValue{\lTmpaInt }
        [O] 625
    [I] \prgReturn{625}
    [O] 625
[O] 625
\end{codehigh}

\section{Definitions of Functions}

Within \verb!expl3!, there are eight commands for defining new functions,
which is good for power users.

\begin{minipage}{0.5\textwidth}
\begin{code}[language=latex/latex3]
\cs_new:Npn
\cs_new_nopar:Npn
\cs_new_protected:Npn
\cs_new_protected_nopar:Npn
\end{code}
\end{minipage}%
\begin{minipage}{0.5\textwidth}
\begin{code}[language=latex/latex3]
\cs_new:Nn
\cs_new_nopar:Nn
\cs_new_protected:Nn
\cs_new_protected_nopar:Nn
\end{code}
\end{minipage}

Within \verb!functional! package, there is only one command (\cs{prgNewFunction})
for defining new functions, which is good for regular users.
The created functions are always protected and accept \verb!\par! in their arguments.

Since \verb!functional! package gets the results of functions by evaluation
(including expansion and execution by \TeX), it is natural to protect all functions.

\section{Variants of Arguments}

Within \verb!expl3!, there are several expansion variants for arguments,
and many expansion functions for expanding them, which are necessary for power users.

\begin{minipage}{0.5\textwidth}
\begin{code}[language=latex/latex3]
\module_foo:c
\module_bar:e
\module_bar:x
\module_bar:f
\module_bar:o
\module_bar:V
\module_bar:v
\end{code}
\end{minipage}%
\begin{minipage}{0.5\textwidth}
\begin{code}[language=latex/latex3]
\exp_args:Nc
\exp_args:Ne
\exp_args:Nx
\exp_args:Nf
\exp_args:No
\exp_args:NV
\exp_args:Nv
\end{code}
\end{minipage}

Within \verb!functional! package, there are only three variants
(\verb!c!, \verb!e!, \verb!V!) are provided, and these variants are defined
as functions (\cs{expName}, \cs{expWhole}, \cs{expValue}, respectively),
which are easier to use for regular users.

\begin{demohigh}
\newcommand\test{uvw}
\expName{test}
\end{demohigh}

\begin{demohigh}
\newcommand\test{uvw}
\expWhole{111\test222}
\end{demohigh}

\begin{demohigh}
\intSet\lTmpaInt{123}
\expValue\lTmpaInt
\end{demohigh}

The most interesting feature is that you can compose these functions.
For example, you can easily get the \verb!v! variant of \verb!expl3! by
simply composing \cs{expName} and \cs{expValue} functions:

\begin{demohigh}
\intSet\lTmpaInt{123}
\expValue{\expName{lTmpaInt}}
\end{demohigh}

\chapter{Functional Progarmming (\texttt{Prg})}

\section{Deﬁning Functions and Conditionals}

\begin{function}{\prgNewFunction}
\begin{syntax}
\cs{prgNewFunction} \meta{function} \Arg{argument specification} \Arg{code}
\end{syntax}
Creates protected \meta{function} for evaluating the \meta{code}.
Within the \meta{code}, the parameters (\verb|#1|, \verb|#2|,
\emph{etc.}) will be replaced by those absorbed by the function.
The returned value \emph{must} be passed with \cs{prgReturn} function.
The definition is global and an error results if the
\meta{function} is already defined.\par
The \Arg{argument specification} in a list of letters,
where each letter is one of the following argument specifiers
(nearly all of them are \texttt{M} or \texttt{m} for functions provided by this package):\par
{\centering\begin{tabular}{ll}
%\hline
  \texttt{M} & single-token argument, which will be manipulated first \\
  \texttt{m} & multi-token argument, which will be manipulated first \\
  \texttt{N} & single-token argument, which will not be manipulated first \\
  \texttt{n} & multi-token argument, which will not be manipulated first \\
%\hline
\end{tabular}\par}
The argument manipulation for argument type \texttt{M} or \texttt{m}
is: if the argument starts with a function defined with \cs{prgNewFunction},
the argument will be evaluated and replaced with the returned value.
\end{function}

\begin{function}{\prgSetEqFunction}
\begin{syntax}
\cs{prgSetEqFunction} \meta{function_1} \meta{function_2}
\end{syntax}
Sets \meta{function_1} as an alias of \meta{function_2}.
\end{function}

\begin{function}{\prgNewConditional}
\begin{syntax}
\cs{prgNewConditional} \meta{function} \Arg{argument specification} \Arg{code}
\end{syntax}
Creates protected conditional \meta{function} for evaluating the \meta{code}.
The returned value of the \meta{function} \emph{must} be either |\cTrueBool|
or |\cFalseBool| and be passed with \cs{prgReturn} function..
The definition is global and an error results if the \meta{function} is already defined.
\par
Assume the \meta{function} is |\fooIfBar|, then another three functions
are also created at the same time: |\fooIfBarT|, |\fooIfBarF|, and |\fooIfBarTF|.
They have extra arguments which are \Arg{true code} or/and \Arg{false code}.
For example, if you write
\begin{codehigh}
\prgNewConditional \fooIfBar {Mm} {code with return value \cTrueBool or \cFalseBool}
\end{codehigh}
Then the following four functions are created:
\begin{itemize}
 \item |\fooIfBar| \meta{arg_1} \Arg{arg_2}
 \item |\fooIfBarT| \meta{arg_1} \Arg{arg_2} \Arg{true code}
 \item |\fooIfBarF| \meta{arg_1} \Arg{arg_2} \Arg{false code}
 \item |\fooIfBarTF| \meta{arg_1} \Arg{arg_2} \Arg{true code} \Arg{false code}
\end{itemize}
\end{function}

\section{Returning Values and Printing Tokens}

Just like \LuaTeX, \pkg{functional} package also provides \cs{prgReturn} and \cs{prgPrint} functions.

\begin{function}{\prgReturn}
\begin{syntax}
\cs{prgReturn} \Arg{tokens}
\end{syntax}
Returns \meta{tokens} as result of current function or conditional.
This function is normally used in the \meta{code} of \cs{prgNewFunction}
or \cs{prgNewConditional}, and it \emph{must} be the last function evaluated in the \meta{code}.
If it is missing, the return value of the last function evaluated in the \meta{code}
is returned. Therefore, the following two examples produce the same output:
\begin{codehigh}
\IgnoreSpacesOn
\prgNewFunction \mathSquare { m } {
  \intSet \lTmpaInt {\intEval {#1 * #1}}
  \prgReturn {\expValue \lTmpaInt}
}
\IgnoreSpacesOff
\mathSquare{5}
\end{codehigh}
\begin{codehigh}
\IgnoreSpacesOn
\prgNewFunction \mathSquare { m } {
  \intSet \lTmpaInt {\intEval {#1 * #1}}
  \expValue \lTmpaInt
}
\IgnoreSpacesOff
\mathSquare{5}
\end{codehigh}
\pkg{Functional} package takes care of return values,
and only print them to the input stream if the outer most functions are evaluated.
\end{function}

\begin{function}{\prgPrint}
\begin{syntax}
\cs{prgPrint} \Arg{tokens}
\end{syntax}
Prints \meta{tokens} directly to the input stream.
If there is no function defined with \cs{prgNewFunction} in \meta{tokens},
you can omit \cs{prgPrint} and write only \meta{tokens}.
But if there is any function defined with \cs{prgNewFunction} in \meta{tokens},
you \emph{have to} use \cs{prgPrint} function.
\end{function}

\section{Running Code with Anonymous Functions}

\begin{function}{\prgDo}
\begin{syntax}
\cs{prgDo} \Arg{code}
\end{syntax}
Treats \meta{code} as an anonymous function without arguments and evaluates it.
\end{function}

\begin{function}{\prgRunOneArgCode,\prgRunTwoArgCode,\prgRunThreeArgCode,\prgRunFourArgCode}
\begin{syntax}
\cs{prgRunOneArgCode} \Arg{arg_1} \Arg{code}
\cs{prgRunTwoArgCode} \Arg{arg_1} \Arg{arg_2} \Arg{code}
\cs{prgRunThreeArgCode} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{code}
\cs{prgRunFourArgCode} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{code}
\end{syntax}
Treats \meta{code} as an anonymous function with one to four arguments respectively,
and evaluates it. In evaluating the \meta{code}, \pkg{functional} package first evaluates
\meta{arg_1} to \meta{arg_4}, then replaces |#1| to |#4| in \meta{code}
with the return values respectively.
\end{function}

\chapter{Argument Using (\texttt{Use})}

\section{Evaluating Functions}

\begin{function}{\evalWhole}
\begin{syntax}
\cs{evalWhole} \Arg{tokens}
\end{syntax}
Evaluates all functions (defined with \cs{prgNewFunction}) in \meta{tokens}
and replaces them with their return values, then returns the resulting tokens.
\begin{codehigh}
\tlSet \lTmpaTl {a\intEval{2*3}b}
\tlSet \lTmpbTl {\evalWhole {a\intEval{2*3}b}}
\end{codehigh}
In the above example, |\lTmpaTl| contains |a\intEval{2*3}b|,
while |\lTmpbTl| contains |a6b|.
\end{function}

\begin{function}{\evalNone}
\begin{syntax}
\cs{evalNone} \Arg{tokens}
\end{syntax}
Prevents the evaluation of its argument, returning \meta{tokens} without touching them.
\begin{codehigh}
\tlSet \lTmpaTl {\intEval{2*3}}
\tlSet \lTmpbTl {\evalNone {\intEval{2*3}}}
\end{codehigh}
In the above example, |\lTmpaTl| contains |6|,
while |\lTmpbTl| contains |\intEval{2*3}|.
\end{function}

\section{Expanding Tokens}

\begin{function}{\expName}
\begin{syntax}
\cs{expName} \Arg{control sequence name}
\end{syntax}
Expands the \meta{control sequence name} until only characters
remain, then converts this into a control sequence and returns it.
The \meta{control sequence name} must consist of character tokens %,
%typically a mixture of category code $10$ (space), $11$ (letter) and $12$ (other).
when exhaustively expanded.%
%\begin{texnote}
%Protected macros that appear in a \texttt{c}-type argument are
%expanded despite being protected; \cs{exp_not:n} also has no
%effect.  An internal error occurs if non-characters or active
%characters remain after full expansion, as the conversion to a
%control sequence is not possible.
%\end{texnote}
\end{function}

\begin{function}{\expValue}
\begin{syntax}
\cs{expValue} \meta{variable}
\end{syntax}
Recovers the content of a \meta{variable} and returns the value.
An error is raised if the variable does not exist or if it is invalid.
Note that it is the same as \cs{tlUse} for \meta{tl var}, or \cs{intUse} for \meta{int var}.
\end{function}

\begin{function}{\expWhole}
\begin{syntax}
\cs{expWhole} \Arg{tokens}
\end{syntax}
Expands the \meta{tokens} exhaustively and returns the result.
\end{function}

\begin{function}{\unExpand}
\begin{syntax}
\cs{unExpand} \Arg{tokens}
\end{syntax}
Prevents expansion of the \meta{tokens} inside the argument of \cs{expWhole} function.
The argument of \cs{unExpand} \emph{must} be surrounded by braces.
%\begin{texnote}
%This is the \eTeX{} \tn{unexpanded} primitive.  In an
%|x|-expanding definition (\cs{cs_new:Npx}), \cs{exp_not:n}~|{#1}|
%is equivalent to |##1| rather than to~|#1|, namely it inserts the
%two characters |#| and~|1|.  In an |e|-type argument
%\cs{exp_not:n}~|{#}| is equivalent to |#|, namely it inserts the
%character~|#|.
%\end{texnote}
\end{function}

\begin{function}{\onlyName}
\begin{syntax}
\cs{onlyName} \Arg{tokens}
\end{syntax}
Expands the \meta{tokens} until only characters remain, and then
converts this into a control sequence.
Further expansion of this control sequence is then inhibited
inside the argument of \cs{expWhole} function.
%\begin{texnote}
%Protected macros that appear in a \texttt{c}-type argument are
%expanded despite being protected; \cs{exp_not:n} also has no
%effect.  An internal error occurs if non-characters or active
%characters remain after full expansion, as the conversion to a
%control sequence is not possible.
%\end{texnote}
\end{function}

\begin{function}{\onlyValue}
\begin{syntax}
\cs{onlyValue} \meta{variable}
\end{syntax}
Recovers the content of the \meta{variable}, then prevents expansion
of this material inside the argument of \cs{expWhole} function.
\end{function}

\section{Using Tokens}

\begin{function}{\useOne,\gobbleOne}
\begin{syntax}
\cs{useOne} \Arg{argument}
\cs{gobbleOne} \Arg{argument}
\end{syntax}
The function \cs{useOne} absorbs one argument and returns it.
%\begin{texnote}
%The \cs{UseOne} function is equivalent to \LaTeXe{}'s \tn{@firstofone}.
%\end{texnote}
\cs{gobbleOne} absorbs one argument and returns nothing.
%\begin{texnote}
%These are equivalent to \LaTeXe{}'s \tn{@gobble}, \tn{@gobbbletwo},
%\emph{etc.}
%\end{texnote}
For example
\begin{demohigh}
\useOne{abc}\gobbleOne{ijk}\useOne{xyz}
\end{demohigh}
\end{function}

\begin{function}{\useGobble,\gobbleUse}
\begin{syntax}
\cs{useGobble} \Arg{arg_1} \Arg{arg_2}
\cs{gobbleUse} \Arg{arg_1} \Arg{arg_2}
\end{syntax}
These functions absorb two arguments.
The function \cs{useGobble} discards the second argument,
and returns the content of the first argument.
\cs{gobbleUse} discards the first argument,
and returns the content of the second argument.
%\begin{texnote}
%These are equivalent to \LaTeXe{}'s \tn{@firstoftwo} and
%\tn{@secondoftwo}.
%\end{texnote}
For example
\begin{demohigh}
\useGobble{abc}{uvw}\gobbleUse{abc}{uvw}
\end{demohigh}
\end{function}

\chapter{Control Structures (\texttt{Bool})}

\section{Constant and Scratch Booleans}

\begin{variable}{\cTrueBool,\cFalseBool}
Constants that represent \verb|true| and \verb|false|, respectively. Used to
implement predicates. For example
\begin{demohigh}
\boolVarIfTF \cTrueBool {\prgReturn{True!}} {\prgReturn{False!}}
\boolVarIfTF \cFalseBool {\prgReturn{True!}} {\prgReturn{False!}}
\end{demohigh}
\end{variable}

\begin{variable}{\lTmpaBool,\lTmpbBool,\lTmpcBool,\lTmpiBool,\lTmpjBool,\lTmpkBool}
Scratch booleans for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaBool,\gTmpbBool,\gTmpcBool,\gTmpiBool,\gTmpjBool,\gTmpkBool}
Scratch booleans for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Boolean Expressions}

As we have a boolean datatype and predicate functions returning
boolean \meta{true} or \meta{false} values, it seems only fitting
that we also provide a parser for \meta{boolean expressions}.

A boolean expression is an expression which given input in the form
of predicate functions and boolean variables, return boolean
\meta{true} or \meta{false}. It supports the logical operations And,
Or and Not as the well-known infix operators \verb|&&| and \verb"||" and
prefix~\verb|!| with their usual precedences (namely, \verb|&&| binds
more tightly than \verb"||"). In addition to this, parentheses can be
used to isolate sub-expressions. For example,
\begin{codehigh}
\intCompare {1} = {1} &&
  (
    \intCompare {2} = {3} ||
    \intCompare {4} < {4} ||
    \strIfEq {abc} {def}
  ) &&
! \intCompare {2} = {4}
\end{codehigh}
is a valid boolean expression.

Contrarily to some other programming languages, the operators \verb|&&| and
\verb"||" evaluate both operands in all cases, even when the first
operand is enough to determine the result.

\section{Creating and Setting Booleans}

\begin{function}{\boolNew}
\begin{syntax}
\cs{boolNew} \meta{boolean}
\end{syntax}
Creates a new \meta{boolean} or raises an error if the
name is already taken. The declaration is global. The
\meta{boolean} is initially \texttt{false}.
\end{function}

\begin{function}{\boolConst}
\begin{syntax}
\cs{boolConst} \meta{boolean} \Arg{boolexpr}
\end{syntax}
Creates a new constant \meta{boolean} or raises an error if the name
is already taken. The value of the \meta{boolean} is set globally to
the result of evaluating the \meta{boolexpr}.
For example
\begin{codehigh}
\boolConst \cFooSomeBool {\intCompare{3}>{2}}
\boolVarLog \cFooSomeBool
\end{codehigh}
\end{function}

\begin{function}{\boolSet}
\begin{syntax}
\cs{boolSet} \meta{boolean} \Arg{boolexpr}
\end{syntax}
Evaluates the \meta{boolean expression} and sets the \meta{boolean} variable to
the logical truth of this evaluation.
For example
\begin{codehigh}
\boolSet \lTmpaBool {\intCompare{3}<{4}}
\boolVarLog \lTmpaBool
\end{codehigh}
\begin{codehigh}
\boolSet \lTmpaBool {\intCompare{3}<{4} && \strIfEq{abc}{uvw}}
\boolVarLog \lTmpaBool
\end{codehigh}
\end{function}

\begin{function}{\boolSetTrue}
\begin{syntax}
\cs{boolSetTrue} \meta{boolean}
\end{syntax}
Sets \meta{boolean} logically \texttt{true}.
\end{function}

\begin{function}{\boolSetFalse}
\begin{syntax}
\cs{boolSetFalse} \meta{boolean}
\end{syntax}
Sets \meta{boolean} logically \texttt{false}.
\end{function}

\begin{function}{\boolSetEq}
\begin{syntax}
\cs{boolSetEq} \meta{boolean_1} \meta{boolean_2}
\end{syntax}
Sets \meta{boolean_1} to the current value of \meta{boolean_2}.
For example
\begin{codehigh}
\boolSetTrue \lTmpaBool
\boolSetEq \lTmpbBool \lTmpaBool
\boolVarLog \lTmpbBool
\end{codehigh}
\end{function}

\section{Viewing Booleans}

\begin{function}{\boolLog}
\begin{syntax}
\cs{boolLog} \Arg{boolean expression}
\end{syntax}
Writes the logical truth of the \meta{boolean expression} in the log file.
\end{function}

\begin{function}{\boolVarLog}
\begin{syntax}
\cs{boolVarLog} \meta{boolean}
\end{syntax}
Writes the logical truth of the \meta{boolean} in the log file.
\end{function}

\begin{function}{\boolShow}
\begin{syntax}
\cs{boolShow} \Arg{boolean expression}
\end{syntax}
Displays the logical truth of the \meta{boolean expression} on the terminal.
\end{function}

\begin{function}{\boolVarShow}
\begin{syntax}
\cs{boolVarShow} \meta{boolean}
\end{syntax}
Displays the logical truth of the \meta{boolean} on the terminal.
\end{function}

\section{Booleans and Conditionals}

\begin{function}{\boolIfExist,\boolIfExistT,\boolIfExistF,\boolIfExistTF}
\begin{syntax}
\cs{boolIfExist} \meta{boolean}
\cs{boolIfExistT} \meta{boolean} \Arg{true code}
\cs{boolIfExistF} \meta{boolean} \Arg{false code}
\cs{boolIfExistTF} \meta{boolean} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{boolean} is currently defined.  This does not
check that the \meta{boolean} really is a boolean variable.
For example
\begin{demohigh}
\boolIfExistTF \lTmpaBool {\prgReturn{Yes}} {\prgReturn{No}}
\boolIfExistTF \lFooUndefinedBool {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\boolVarIf,\boolVarIfT,\boolVarIfF,\boolVarIfTF}
\begin{syntax}
\cs{boolVarIf} \meta{boolean}
\cs{boolVarIfT} \meta{boolean} \Arg{true code}
\cs{boolVarIfF} \meta{boolean} \Arg{false code}
\cs{boolVarIfTF} \meta{boolean} \Arg{true code} \Arg{false code}
\end{syntax}
Tests the current truth of \meta{boolean}, and continues evaluation
based on this result. For example
\begin{demohigh}
\boolSetTrue \lTmpaBool
\boolVarIfTF \lTmpaBool {\prgReturn{True!}} {\prgReturn{False!}}
\boolSetFalse \lTmpaBool
\boolVarIfTF \lTmpaBool {\prgReturn{True!}} {\prgReturn{False!}}
\end{demohigh}
\end{function}

\begin{function}{\boolVarNot,\boolVarNotT,\boolVarNotF,\boolVarNotTF}
\begin{syntax}
\cs{boolVarNot} \meta{boolean}
\cs{boolVarNotT} \meta{boolean} \Arg{true code}
\cs{boolVarNotF} \meta{boolean} \Arg{false code}
\cs{boolVarNotTF} \meta{boolean} \Arg{true code} \Arg{false code}
\end{syntax}
Evaluates \meta{true code} if \meta{boolean} is \verb!false!,
and \meta{false code} if \meta{boolean} is \verb!true!.
For example
\begin{demohigh}
\boolVarNotTF {\intCompare{3}>{2}} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\boolVarAnd,\boolVarAndT,\boolVarAndF,\boolVarAndTF}
\begin{syntax}
\cs{boolVarAnd} \meta{boolean_1} \meta{boolean_2}
\cs{boolVarAndT} \meta{boolean_1} \meta{boolean_2} \Arg{true code}
\cs{boolVarAndF} \meta{boolean_1} \meta{boolean_2} \Arg{false code}
\cs{boolVarAndTF} \meta{boolean_1} \meta{boolean_2} \Arg{true code} \Arg{false code}
\end{syntax}
Implements the \enquote{And} operation between two booleans,
hence is \texttt{true} if both are \texttt{true}.
%Contrarily to the infix operator \verb|&&|,
%The \meta{boolean_2} is only evaluated if it is needed to determine the result of
%\cs{boolVarAnd}.
For example
\begin{demohigh}
\boolVarAndTF {\intCompare{3}>{2}} {\intIfOdd{6}} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\boolVarOr,\boolVarOrT,\boolVarOrF,\boolVarOrTF}
\begin{syntax}
\cs{boolVarOr} \meta{boolean_1} \meta{boolean_2}
\cs{boolVarOrT} \meta{boolean_1} \meta{boolean_2} \Arg{true code}
\cs{boolVarOrF} \meta{boolean_1} \meta{boolean_2} \Arg{false code}
\cs{boolVarOrTF} \meta{boolean_1} \meta{boolean_2} \Arg{true code} \Arg{false code}
\end{syntax}
Implements the \enquote{Or} operation between two booleans,
hence is \texttt{true} if either one is \texttt{true}.
%Contrarily to the infix operator \verb"||",
%The \meta{boolean_2} is only evaluated if it is needed to determine the result of
%\cs{boolVarOr}.
For example
\begin{demohigh}
\boolVarOrTF {\intCompare{3}>{2}} {\intIfOdd{6}} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\boolVarXor,\boolVarXorT,\boolVarXorF,\boolVarXorTF}
\begin{syntax}
\cs{boolVarXor} \meta{boolean_1} \meta{boolean_2}
\cs{boolVarXorT} \meta{boolean_1} \meta{boolean_2} \Arg{true code}
\cs{boolVarXorF} \meta{boolean_1} \meta{boolean_2} \Arg{false code}
\cs{boolVarXorTF} \meta{boolean_1} \meta{boolean_2} \Arg{true code} \Arg{false code}
\end{syntax}
Implements an \enquote{exclusive or} operation between two booleans.
For example
\begin{demohigh}
\boolVarXorTF {\intCompare{3}>{2}} {\intIfOdd{6}} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\section{Booleans and Logical Loops}

Loops using either boolean expressions or stored boolean values.

\begin{function}{\boolVarDoUntil}
\begin{syntax}
\cs{boolVarDoUntil} \meta{boolean} \Arg{code}
\end{syntax}
Places the \meta{code} in the input stream for \TeX{} to process,
and then checks the logical value of the \meta{boolean}.  If it is
\texttt{false} then the \meta{code} is inserted into the input
stream again and the process loops until the \meta{boolean} is
\texttt{true}.
\begin{demohigh}
\IgnoreSpacesOn
\boolSetFalse \lTmpaBool
\intZero \lTmpaInt
\clistClear \lTmpaClist
\boolVarDoUntil \lTmpaBool {
  \intIncr \lTmpaInt
  \clistPutRight \lTmpaClist {\expValue\lTmpaInt}
  \intCompareT {\lTmpaInt} = {10} {\boolSetTrue \lTmpaBool}
}
\clistVarJoin \lTmpaClist {:}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\boolVarDoWhile}
\begin{syntax}
\cs{boolVarDoWhile} \meta{boolean} \Arg{code}
\end{syntax}
Places the \meta{code} in the input stream for \TeX{} to process,
and then checks the logical value of the \meta{boolean}.  If it is
\texttt{true} then the \meta{code} is inserted into the input
stream again and the process loops until the \meta{boolean} is
\texttt{false}.
\begin{demohigh}
\IgnoreSpacesOn
\boolSetTrue \lTmpaBool
\intZero \lTmpaInt
\clistClear \lTmpaClist
\boolVarDoWhile \lTmpaBool {
  \intIncr \lTmpaInt
  \clistPutRight \lTmpaClist {\expValue\lTmpaInt}
  \intCompareT {\lTmpaInt} = {10} {\boolSetFalse \lTmpaBool}
}
\clistVarJoin \lTmpaClist {:}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\boolVarUntilDo}
\begin{syntax}
\cs{boolVarUntilDo} \meta{boolean} \Arg{code}
\end{syntax}
This function firsts checks the logical value of the \meta{boolean}.
If it is \texttt{false} the \meta{code} is placed in the input stream
and expanded. After the completion of the \meta{code} the truth
of the \meta{boolean} is re-evaluated. The process then loops
until the \meta{boolean} is \texttt{true}.
\begin{demohigh}
\IgnoreSpacesOn
\boolSetFalse \lTmpaBool
\intZero \lTmpaInt
\clistClear \lTmpaClist
\boolVarUntilDo \lTmpaBool {
  \intIncr \lTmpaInt
  \clistPutRight \lTmpaClist {\expValue\lTmpaInt}
  \intCompareT {\lTmpaInt} = {10} {\boolSetTrue \lTmpaBool}
}
\clistVarJoin \lTmpaClist {:}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\boolVarWhileDo}
\begin{syntax}
\cs{boolVarWhileDo} \meta{boolean} \Arg{code}
\end{syntax}
This function firsts checks the logical value of the \meta{boolean}.
If it is \texttt{true} the \meta{code} is placed in the input stream
and expanded. After the completion of the \meta{code} the truth
of the \meta{boolean} is re-evaluated. The process then loops
until the \meta{boolean} is \texttt{false}.
\begin{demohigh}
\IgnoreSpacesOn
\boolSetTrue \lTmpaBool
\intZero \lTmpaInt
\clistClear \lTmpaClist
\boolVarWhileDo \lTmpaBool {
  \intIncr \lTmpaInt
  \clistPutRight \lTmpaClist {\expValue\lTmpaInt}
  \intCompareT {\lTmpaInt} = {10} {\boolSetFalse \lTmpaBool}
}
\clistVarJoin \lTmpaClist {:}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\chapter{Token Lists (\texttt{Tl})}

\TeX{} works with tokens, and \LaTeX3 therefore provides a number of
functions to deal with lists of tokens.  Token lists may be present
directly in the argument to a function:
\begin{codehigh}
\tlFoo {a collection of \tokens}
\end{codehigh}
or may be stored in a so-called \enquote{token list variable}, which
have the suffix \texttt{Tl}: a token list variable can also be used as
the argument to a function, for example
\begin{codehigh}
\tlVarFoo \lSomeTl
\end{codehigh}
In both cases, functions are available to test and manipulate the lists
of tokens, and these have the module prefix \texttt{Tl}.
In many cases, functions which can be applied to token list variables
are paired with similar functions for application to explicit lists
of tokens: the two \enquote{views} of a token list are therefore collected
together here.

A token list (explicit, or stored in a variable) can be seen either
as a list of \enquote{items},
or a list of \enquote{tokens}. An item is whatever \cs{useOne} would
grab as its argument: a single non-space token or a brace group,
with optional leading explicit space characters (each item is thus
itself a token list). A token is either a normal \texttt{N} argument,
or \verb*| |, \verb|{|, or \verb|}| (assuming normal \TeX{} category codes).
Thus for example
\begin{codehigh}
{Hello} world
\end{codehigh}
contains 6 items (\texttt{Hello}, \texttt{w}, \texttt{o}, \texttt{r},
\texttt{l} and \texttt{d}), but 13 tokens (\verb|{|, \texttt{H}, \texttt{e},
\texttt{l}, \texttt{l}, \texttt{o}, \verb|}|, \verb*| |, \texttt{w}, \texttt{o},
\texttt{r}, \texttt{l} and \texttt{d}).
Functions which act on items are often faster than their analogue acting
directly on tokens.

\section{Constant and Scratch Token Lists}

\begin{variable}{\cSpaceTl}
An explicit space character contained in a token list%
%(compare this with \cs{c_space_token})
. For use where an explicit space is required.
\end{variable}

\begin{variable}{\cEmptyTl}
Constant that is always empty.
\end{variable}

%\begin{variable}{\cNoValueTl}
%A marker for the absence of an argument. This constant \verb|tl| can safely
%be typeset (\emph{cf.}~\cs{qNil}), with the result being \verb|-NoValue-|.
%It is important to note that \cs{cNoValueTl} is constructed such that it
%will \emph{not} match the simple text input \verb|-NoValue-|, \emph{i.e.}
%that
%\begin{demohigh}
%\tlIfEqTF {\tlUse\cNoValueTl} {-NoValue-} {Result{Yes}} {\prgReturn{No}}
%\end{demohigh}
%The \cs{cNoValueTl} marker is intended for
%use in creating document-level interfaces, where it serves as an indicator
%that an (optional) argument was omitted. In particular, it is distinct
%from a simple empty \verb|tl|.
%\end{variable}

\begin{variable}{\lTmpaTl,\lTmpbTl,\lTmpcTl,\lTmpiTl,\lTmpjTl,\lTmpkTl}
Scratch token lists for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaTl,\gTmpbTl,\gTmpcTl,\gTmpiTl,\gTmpjTl,\gTmpkTl}
Scratch token lists for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Creating and Using Token Lists}

\begin{function}{\tlNew}
\begin{syntax}
\cs{tlNew} \meta{tl var}
\end{syntax}
Creates a new \meta{tl var} or raises an error if the
name is already taken. The declaration is global. The
\meta{tl~var} is initially empty.
\begin{codehigh}
\tlNew \lFooSomeTl
\end{codehigh}
\end{function}

\begin{function}{\tlConst}
\begin{syntax}
\cs{tlConst} \meta{tl var} \Arg{token list}
\end{syntax}
Creates a new constant \meta{tl var} or raises an error
if the name is already taken. The value of the
\meta{tl var} is set globally to the \meta{token list}.
\begin{codehigh}
\tlConst \cFooSomeTl {abc}
\end{codehigh}
\end{function}

\begin{function}{\tlUse}
\begin{syntax}
\cs{tlUse} \meta{tl~var}
\end{syntax}
Recovers the content of a \meta{tl~var} and returns the value.
An error is raised if the variable
does not exist or if it is invalid. Note that it is possible to use
a \meta{tl~var} directly without an accessor function.
\begin{codehigh}
\tlUse \lTmpbTl
\end{codehigh}
\end{function}

\begin{function}{\tlToStr}
\begin{syntax}
\cs{tlToStr} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string}, returning the
resulting character tokens. A \meta{string}
is a series of tokens with category code $12$ (other) with the exception
of spaces, which retain category code $10$ (space).
\begin{demohigh}
\tlToStr {12\abc34}
\end{demohigh}
%This function requires only a single expansion.
%Its argument \emph{must} be braced.
%\begin{texnote}
%This is the \eTeX{} primitive \tn{detokenize}.
%Converting a \meta{token list} to a \meta{string} yields a
%concatenation of the string representations of every token in the
%\meta{token list}.
%The string representation of a control sequence is
%\begin{itemize}
%\item an escape character, whose character code is given by the
%internal parameter \tn{escapechar}, absent if the
%\tn{escapechar} is negative or greater than the largest
%character code;
%\item the control sequence name, as defined by \cs{cs_to_str:N};
%\item a space, unless the control sequence name is a single
%character whose category at the time of expansion of
%\cs{tl_to_str:n} is not \enquote{letter}.
%\end{itemize}
%The string representation of an explicit character token is that
%character, doubled in the case of (explicit) macro parameter
%characters (normally \verb|#|).
%In particular, the string representation of a token list may
%depend on the category codes in effect when it is evaluated, and
%the value of the \tn{escapechar}: for instance |\tl_to_str:n {\a}|
%normally produces the three character \enquote{backslash},
%\enquote{lower-case a}, \enquote{space}, but it may also produce a
%single \enquote{lower-case a} if the escape character is negative
%and \texttt{a} is currently not a letter.
%\end{texnote}
\end{function}

\begin{function}{\tlVarToStr}
\begin{syntax}
\cs{tlVarToStr} \meta{tl var}
\end{syntax}
Converts the content of the \meta{tl var} to a string, returning the
resulting character tokens. A \meta{string}
is a series of tokens with category code $12$ (other) with the exception
of spaces, which retain category code $10$ (space).
\begin{demohigh}
\tlSet \lTmpaTl {12\abc34}
\tlVarToStr \lTmpaTl
\end{demohigh}
\end{function}

\section{Viewing Token Lists}

\begin{function}{\tlLog}
\begin{syntax}
\cs{tlLog} \Arg{token list}
\end{syntax}
Writes the \meta{token list} in the log file. See also
\cs{tlShow} which displays the result in the terminal.
\begin{codehigh}
\tlLog {123\abc456}
\end{codehigh}
\end{function}

\begin{function}{\tlVarLog}
\begin{syntax}
\cs{tlVarLog} \meta{tl var}
\end{syntax}
Writes the content of the \meta{tl var} in the log file. See also
\cs{tlVarShow} which displays the result in the terminal.
\begin{codehigh}
\tlSet \lTmpaTl {123\abc456}
\tlVarLog \lTmpaTl
\end{codehigh}
\end{function}

\begin{function}{\tlShow}
\begin{syntax}
\cs{tlShow} \Arg{token list}
\end{syntax}
Displays the \meta{token list} on the terminal.
\begin{codehigh}
\tlShow {123\abc456}
\end{codehigh}
%\begin{texnote}
%This is similar to the \eTeX{} primitive \tn{showtokens}, wrapped
%to a fixed number of characters per line.
%\end{texnote}
\end{function}

\begin{function}{\tlVarShow}
\begin{syntax}
\cs{tlVarShow} \meta{tl var}
\end{syntax}
Displays the content of the \meta{tl var} on the terminal.
\begin{codehigh}
\tlSet \lTmpaTl {123\abc456}
\tlVarShow \lTmpaTl
\end{codehigh}
%\begin{texnote}
%This is similar to the \TeX{} primitive \tn{show}, wrapped to a
%fixed number of characters per line.
%\end{texnote}
\end{function}

\section{Setting Token List Variables}

\begin{function}{\tlSet}
\begin{syntax}
\cs{tlSet} \meta{tl~var} \Arg{tokens}
\end{syntax}
Sets \meta{tl~var} to contain \meta{tokens},
removing any previous content from the variable.
\begin{demohigh}
\tlSet \lTmpiTl {\intMathMult{4}{5}}
\tlUse \lTmpiTl
\end{demohigh}
\end{function}

\begin{function}{\tlSetEq}
\begin{syntax}
\cs{tlSetEq} \meta{tl var_1} \meta{tl var_2}
\end{syntax}
Sets the content of \meta{tl var_1} equal to that of \meta{tl var_2}.
\begin{demohigh}
\tlSet \lTmpaTl {abc}
\tlSetEq \lTmpbTl \lTmpaTl
\tlUse \lTmpbTl
\end{demohigh}
\end{function}

\begin{function}{\tlClear}
\begin{syntax}
\cs{tlClear} \meta{tl~var}
\end{syntax}
Clears all entries from the \meta{tl~var}.
\begin{demohigh}
\tlSet \lTmpjTl {One}
\tlClear \lTmpjTl
\tlSet \lTmpjTl {Two}
\tlUse \lTmpjTl
\end{demohigh}
\end{function}

\begin{function}{\tlClearNew}
\begin{syntax}
\cs{tlClearNew} \meta{tl var}
\end{syntax}
Ensures that the \meta{tl var} exists globally by applying
\cs{tlNew} if necessary, then applies \cs{tlClear} to leave
the \meta{tl var} empty.
\begin{codehigh}
\tlClearNew \lFooSomeTl
\end{codehigh}
\end{function}

\begin{function}{\tlConcat}
\begin{syntax}
\cs{tlConcat} \meta{tl var_1} \meta{tl var_2} \meta{tl var_3}
\end{syntax}
Concatenates the content of \meta{tl var_2} and \meta{tl var_3}
together and saves the result in \meta{tl var_1}. The \meta{tl var_2}
is placed at the left side of the new token list.
\begin{demohigh}
\tlSet \lTmpbTl {con}
\tlSet \lTmpcTl {cat}
\tlConcat \lTmpaTl \lTmpbTl \lTmpcTl
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlPutLeft}
\begin{syntax}
\cs{tlPutLeft} \meta{tl~var} \Arg{tokens}
\end{syntax}
Appends \meta{tokens} to the left side of the current content of \meta{tl~var}.
\begin{demohigh}
\tlSet \lTmpkTl {Functional}
\tlPutLeft \lTmpkTl {Hello}
\tlUse \lTmpkTl
\end{demohigh}
\end{function}

\begin{function}{\tlPutRight}
\begin{syntax}
\cs{tlPutRight} \meta{tl~var} \Arg{tokens}
\end{syntax}
Appends \meta{tokens} to the right side of the current content of \meta{tl~var}.
\begin{demohigh}
\tlSet \lTmpkTl {Functional}
\tlPutRight \lTmpkTl {World}
\tlUse \lTmpkTl
\end{demohigh}
\end{function}

\section{Replacing Tokens}

Within token lists, replacement takes place at the top level: there is
no recursion into brace groups (more precisely, within a group defined by
a categroy code $1$/$2$ pair).

\begin{function}{\tlVarReplaceOnce}
\begin{syntax}
\cs{tlVarReplaceOnce} \meta{tl var} \Arg{old tokens} \Arg{new tokens}
\end{syntax}
Replaces the first (leftmost) occurrence of \meta{old tokens} in the
\meta{tl var} with \meta{new tokens}. \meta{Old tokens}
cannot contain \verb|{|, \verb|}| or \verb|#|
(more precisely, explicit character tokens with category code $1$
(begin-group) or $2$ (end-group), and tokens with category code $6$).
\begin{demohigh}
\tlSet \lTmpaTl {1{bc}2bc3}
\tlVarReplaceOnce \lTmpaTl {bc} {xx}
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlVarReplaceAll}
\begin{syntax}
\cs{tlVarReplaceAll} \meta{tl var} \Arg{old tokens} \Arg{new tokens}
\end{syntax}
Replaces all occurrences of \meta{old tokens} in the
\meta{tl var} with \meta{new tokens}. \meta{Old tokens}
cannot contain \verb|{|, \verb|}| or \verb|#|
(more precisely, explicit character tokens with category code $1$
(begin-group) or $2$ (end-group), and tokens with category code $6$).
As this function
operates from left to right, the pattern \meta{old tokens}
may remain after the replacement (see \cs{tlVarRemoveAll} for an example).
\begin{demohigh}
\tlSet \lTmpaTl {1{bc}2bc3}
\tlVarReplaceAll \lTmpaTl {bc} {xx}
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlVarRemoveOnce}
\begin{syntax}
\cs{tlVarRemoveOnce} \meta{tl var} \Arg{tokens}
\end{syntax}
Removes the first (leftmost) occurrence of \meta{tokens} from the
\meta{tl var}. \meta{Tokens} cannot contain \verb|{|, \verb|}| or \verb|#|
(more precisely, explicit character tokens with category code $1$
(begin-group) or $2$ (end-group), and tokens with category code $6$).
\begin{demohigh}
\tlSet \lTmpaTl {1{bc}2bc3}
\tlVarRemoveOnce \lTmpaTl {bc}
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlVarRemoveAll}
\begin{syntax}
\cs{tlVarRemoveAll} \meta{tl var} \Arg{tokens}
\end{syntax}
Removes all occurrences of \meta{tokens} from the
\meta{tl var}. \meta{Tokens} cannot contain \verb|{|, \verb|}| or \verb|#|
(more precisely, explicit character tokens with category code $1$
(begin-group) or $2$ (end-group), and tokens with category code $6$).
As this function
operates from left to right, the pattern \meta{tokens}
may remain after the removal, for instance,
\begin{demohigh}
\tlSet \lTmpaTl {abbccd}
\tlVarRemoveAll \lTmpaTl {bc}
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlTrimSpaces}
\begin{syntax}
\cs{tlTrimSpaces} \Arg{token list}
\end{syntax}
Removes any leading and trailing explicit space characters
(explicit tokens with character code $32$ and category code $10$)
from the \meta{token list} and returns the result.
\begin{demohigh}
Foo\tlTrimSpaces { 12 34 }Bar
\end{demohigh}
%\begin{texnote}
%The result is returned within \tn{unexpanded}, which means that the token
%list does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\tlVarTrimSpaces}
\begin{syntax}
\cs{tlVarTrimSpaces} \meta{tl var}
\end{syntax}
Sets the \meta{tl var} to contain the result of removing any leading
and trailing explicit space characters (explicit tokens with
character code $32$ and category code $10$) from its contents.
\begin{demohigh}
\tlSet \lTmpaTl { 12 34 }
\tlVarTrimSpaces \lTmpaTl
Foo\tlUse \lTmpaTl Bar
\end{demohigh}
\end{function}

\section{Working with the Content of Token Lists}

\begin{function}{\tlCount}
\begin{syntax}
\cs{tlCount} \Arg{tokens}
\end{syntax}
Counts the number of \meta{items} in \meta{tokens} and returns this information.
Unbraced tokens count as one element as do each token group (\verb|{|$\cdots$\verb|}|).
This process ignores any unprotected spaces within \meta{tokens}. %See also \cs{tlVarCount}.
%This function requires three expansions, giving an \meta{integer denotation}.
\begin{demohigh}
\tlCount {12\abc34}
\end{demohigh}
\end{function}

\begin{function}{\tlVarCount}
\begin{syntax}
\cs{tlVarCount} \meta{tl var}
\end{syntax}
Counts the number of \meta{items} in the \meta{tl var} and returns this information.
Unbraced tokens count as one element as do each token group (\verb|{|$\cdots$\verb|}|).
This process ignores any unprotected spaces within the \meta{tl var}. %See also \cs{tlCount}.
%This function requires three expansions, giving an \meta{integer denotation}.
\begin{demohigh}
\tlSet \lTmpaTl {12\abc34}
\tlVarCount \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlHead}
\begin{syntax}
\cs{tlHead} \Arg{token list}
\end{syntax}
Returns the first \meta{item} in the \meta{token list},
discarding the rest of the \meta{token list}.
All leading explicit space characters
(explicit tokens with character code $32$ and category code $10$)
are discarded; for example
\begin{demohigh}
\fbox {1\tlHead{ abc }2}
\fbox {1\tlHead{  abc }2}
\end{demohigh}
If the \enquote{head} is a brace group, rather than a single token,
the braces are removed, and so
\begin{codehigh}
\tlHead { { ab} c }
\end{codehigh}
yields \verb*| ab|.
A blank \meta{token list} (see \cs{tlIfBlank}) results in
\cs{tlHead} returning nothing.
%\begin{texnote}
%The result is returned within \cs{exp_not:n}, which means that the token
%list does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\tlVarHead}
\begin{syntax}
\cs{tlVarHead} \meta{tl var}
\end{syntax}
Returns the first \meta{item} in the \meta{tl var},
discarding the rest of the \meta{tl var}.
All leading explicit space characters (explicit tokens with character code $32$
and category code $10$) are discarded.
\begin{demohigh}
\tlSet \lTmpaTl {HELLO}
\tlVarHead \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlTail}
\begin{syntax}
\cs{tlTail} \Arg{token list}
\end{syntax}
Discards all leading explicit space characters
(explicit tokens with character code $32$ and category code $10$)
and the first \meta{item} in the \meta{token list}, and returns the
remaining tokens. Thus for example
\begin{codehigh}
\tlTail { a {bc} d }
\end{codehigh}
and
\begin{codehigh}
\tlTail {  a {bc} d }
\end{codehigh}
both return \verb*| {bc} d |.  A blank \meta{token list} (see \cs{tlIfBlank})
results in \cs{tlTail} returning nothing.
%\begin{texnote}
%The result is returned within \cs{exp_not:n}, which means that the
%token list does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\tlVarTail}
\begin{syntax}
\cs{tlVarTail} \meta{tl var}
\end{syntax}
Discards all leading explicit space characters
(explicit tokens with character code $32$ and category code $10$)
and the first \meta{item} in the \meta{tl var}, and returns the
remaining tokens.
\begin{demohigh}
\tlSet \lTmpaTl {HELLO}
\tlVarTail \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\tlItem,\tlVarItem}
\begin{syntax}
\cs{tlItem} \Arg{token list} \Arg{integer expression}
\cs{tlVarItem} \meta{tl var} \Arg{integer expression}
\end{syntax}
Indexing items in the \meta{token list} from $1$ on the left, this
function evaluates the \meta{integer expression} and returns the
appropriate item from the \meta{token list}.
If the \meta{integer expression} is negative, indexing occurs from
the right of the token list, starting at $-1$ for the right-most item.
If the index is out of bounds, then the function returns nothing.
\begin{demohigh}
\tlItem {abcd} {3}
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\tlRandItem,\tlVarRandItem}
\begin{syntax}
\cs{tlRandItem} \Arg{token list}
\cs{tlVarRandItem} \meta{tl var}
\end{syntax}
Selects and returns a pseudo-random item of the \meta{token list}.
If the \meta{token list} is blank, the result is empty.
%This is not available in older versions of \XeTeX{}.
\begin{demohigh}
\tlRandItem {abcdef}
\tlRandItem {abcdef}
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\section{Mapping over Token Lists}

%All mappings are done at the current group level, \emph{i.e.} any
%local assignments made by the \meta{function} or \meta{code} discussed
%below remain in effect after the loop.

%\begin{function}{\tlMapFunction}
%\begin{syntax}
%\cs{tlMapFunction} \Arg{token list} \meta{function}
%\end{syntax}
%Applies \meta{function} to every \meta{item} in the \meta{token list},
%The \meta{function} receives one argument for each iteration.
%This may be a number of tokens if the \meta{item} was stored within
%braces. Hence the \meta{function} should anticipate receiving
%\texttt{n}-type arguments.
%\end{function}
%
%\begin{function}{\tlVarMapFunction}
%\begin{syntax}
%\cs{tlVarMapFunction} \meta{tl var} \meta{function}
%\end{syntax}
%Applies \meta{function} to every \meta{item} in the \meta{tl var}.
%The \meta{function} receives one argument for each iteration.
%This may be a number of tokens if the \meta{item} was stored within
%braces. Hence the \meta{function} should anticipate receiving
%\texttt{n}-type arguments.
%\end{function}

\begin{function}{\tlMapInline}
\begin{syntax}
\cs{tlMapInline} \Arg{token list} \Arg{inline function}
\end{syntax}
Applies the \meta{inline function} to every \meta{item} stored within the
\meta{token list}. The \meta{inline function}  should consist of code which
receives the \meta{item} as \verb|#1|.
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\tlMapInline {one} {
  \tlPutRight \lTmpaTl {[#1]}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\tlVarMapInline}
\begin{syntax}
\cs{tlVarMapInline} \meta{tl var} \Arg{inline function}
\end{syntax}
Applies the \meta{inline function} to every \meta{item} stored within the
\meta{tl var}. The \meta{inline function} should consist of code which
receives the \meta{item} as \verb|#1|.
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\tlSet \lTmpkTl {one}
\tlVarMapInline \lTmpkTl {
  \tlPutRight \lTmpaTl {[#1]}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\tlMapTokens,\tlVarMapTokens}
%\begin{syntax}
%\cs{tlMapTokens} \Arg{tokens} \Arg{code}
%\cs{tlVarMapTokens} \meta{tl var} \Arg{code}
%\end{syntax}
%Analogue of \cs{tl_map_function:NN} which maps several tokens
%instead of a single function.  The \meta{code} receives each \meta{item} in
%the \meta{tl var} or in \meta{tokens} as a trailing brace group. For
%instance,
%\begin{verbatim}
%\tl_map_tokens:Nn \l_my_tl { \prg_replicate:nn { 2 } }
%\end{verbatim}
%expands to twice each \meta{item} in the \meta{tl var}: for each \meta{item} in
%\cs{l_my_tl} the function \cs{prg_replicate:nn} receives |2| and
%\meta{item} as its two arguments.  The function
%\cs{tl_map_inline:Nn} is typically faster but is not expandable.
%\end{function}

\begin{function}{\tlMapVariable}
\begin{syntax}
\cs{tlMapVariable} \Arg{token list} \meta{variable} \Arg{code}
\end{syntax}
Stores each \meta{item} of the \meta{token list} in turn in the
(token list) \meta{variable} and applies the \meta{code}.  The
\meta{code} will usually make use of the \meta{variable}, but this
is not enforced.  The assignments to the \meta{variable} are local.
Its value after the loop is the last \meta{item} in the
\meta{tl var}, or its original value if the \meta{tl var} is blank.
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\tlMapVariable {one} \lTmpiTl {
  \tlPutRight \lTmpaTl {\expWhole {[\lTmpiTl]}}
}
\prgReturn{\tlUse\lTmpaTl}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\tlVarMapVariable}
\begin{syntax}
\cs{tlVarMapVariable} \meta{tl var} \meta{variable} \Arg{code}
\end{syntax}
Stores each \meta{item} of the \meta{tl var} in turn in the (token
list) \meta{variable} and applies the \meta{code}.  The \meta{code}
will usually make use of the \meta{variable}, but this is not
enforced.  The assignments to the \meta{variable} are local.  Its
value after the loop is the last \meta{item} in the \meta{tl var},
or its original value if the \meta{tl var} is blank.
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\tlSet \lTmpkTl {one}
\tlVarMapVariable \lTmpkTl \lTmpiTl {
  \tlPutRight \lTmpaTl {\expWhole {[\lTmpiTl]}}
}
\prgReturn{\tlUse\lTmpaTl}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\tlMapBreak}
%\begin{syntax}
%\cs{tlMapBreak}
%\end{syntax}
%Used to terminate a tl map function before all
%entries in the \meta{token list variable} have been processed. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\tl_map_inline:Nn \l_my_tl
%{
%\str_if_eq:nnT { #1 } { bingo } { \tl_map_break: }
%Do something useful
%}
%\end{verbatim}
%See also \cs{tl_map_break:n}.
%Use outside of a tl map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before the \meta{tokens} are
%inserted into the input stream.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}
%
%\begin{function}{\tlMapBreakDo}
%\begin{syntax}
%\cs{tlMapBreakDo} \Arg{code}
%\end{syntax}
%Used to terminate a tl map function before all
%entries in the \meta{token list variable} have been processed, inserting
%the \meta{code} after the mapping has ended. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\tl_map_inline:Nn \l_my_tl
%{
%\str_if_eq:nnT { #1 } { bingo }
%{ \tl_map_break:n { <code> } }
%Do something useful
%}
%\end{verbatim}
%Use outside of a tl map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before the \meta{code} is
%inserted into the input stream.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}

\section{Token List Conditionals}

\begin{function}{\tlIfExist,\tlIfExistT,\tlIfExistF,\tlIfExistTF}
\begin{syntax}
\cs{tlIfExist} \meta{tl var}
\cs{tlIfExistT} \meta{tl var} \Arg{true code}
\cs{tlIfExistF} \meta{tl var} \Arg{false code}
\cs{tlIfExistTF} \meta{tl var} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{tl var} is currently defined.  This does not
check that the \meta{tl var} really is a token list variable.
\begin{demohigh}
\tlIfExistTF \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\tlIfExistTF \lFooUndefinedTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\tlIfEmpty,\tlIfEmptyT,\tlIfEmptyF,\tlIfEmptyTF}
\begin{syntax}
\cs{tlIfEmpty} \Arg{token list}
\cs{tlIfEmptyT} \Arg{token list} \Arg{true code}
\cs{tlIfEmptyF} \Arg{token list} \Arg{false code}
\cs{tlIfEmptyTF} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{token list} is entirely empty
(\emph{i.e.}~contains no tokens at all). For example
\begin{demohigh}
\tlIfEmptyTF {abc} {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\tlIfEmptyTF {} {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\tlVarIfEmpty,\tlVarIfEmptyT,\tlVarIfEmptyF,\tlVarIfEmptyTF}
\begin{syntax}
\cs{tlVarIfEmpty} \meta{tl~var}
\cs{tlVarIfEmptyT} \meta{tl~var} \Arg{true code}
\cs{tlVarIfEmptyF} \meta{tl~var} \Arg{false code}
\cs{tlVarIfEmptyTF} \meta{tl~var} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{token list variable} is entirely empty
(\emph{i.e.}~contains no tokens at all). For example
\begin{demohigh}
\tlSet \lTmpaTl {abc}
\tlVarIfEmptyTF \lTmpaTl {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\tlClear \lTmpaTl
\tlVarIfEmptyTF \lTmpaTl {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\tlIfBlank,\tlIfBlankT,\tlIfBlankF,\tlIfBlankTF}
\begin{syntax}
\cs{tlIfBlank} \Arg{token list}
\cs{tlIfBlankT} \Arg{token list} \Arg{true code}
\cs{tlIfBlankF} \Arg{token list} \Arg{false code}
\cs{tlIfBlankTF} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{token list} consists only of blank spaces
(\emph{i.e.} contains no item). The test is \texttt{true} if
\meta{token list} is zero or more explicit space characters
(explicit tokens with character code $32$ and category code $10$),
and is \texttt{false} otherwise.
\begin{demohigh}
\tlIfEmptyTF {  } {\prgReturn{Yes}} {\prgReturn{No}}
\tlIfBlankTF {  } {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\tlIfEq,\tlIfEqT,\tlIfEqF,\tlIfEqTF}
\begin{syntax}
\cs{tlIfEq} \Arg{token list_1} \Arg{token list_2}
\cs{tlIfEqT} \Arg{token list_1} \Arg{token list_2} \Arg{true code}
\cs{tlIfEqF} \Arg{token list_1} \Arg{token list_2} \Arg{false code}
\cs{tlIfEqTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if \meta{token list_1} and \meta{token list_2} contain the
same list of tokens, both in respect of character codes and category
codes. See \cs{strIfEq} if category codes are not important.
For example
\begin{demohigh}
\tlIfEqTF {abc} {abc} {\prgReturn{Yes}} {\prgReturn{No}}
\tlIfEqTF {abc} {xyz} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
%\begin{demohigh}
%\tlSet\lTmpaTl{abc}
%\tlSet\lTmpbTl{abc}
%\tlSet\lTmpcTl{xyz}
%\tlIfEqTF{\tlUse\lTmpaTl}{\tlUse\lTmpbTl}{\prgReturn{Yes}}{\prgReturn{No}}
%\tlIfEqTF{\tlUse\lTmpaTl}{\tlUse\lTmpcTl}{\prgReturn{Yes}}{\prgReturn{No}}
%\end{demohigh}
\end{function}

\begin{function}{\tlVarIfEq,\tlVarIfEqT,\tlVarIfEqF,\tlVarIfEqTF}
\begin{syntax}
\cs{tlVarIfEq} \meta{tl var_1} \meta{tl var_2}
\cs{tlVarIfEqT} \meta{tl var_1} \meta{tl var_2} \Arg{true code}
\cs{tlVarIfEqF} \meta{tl var_1} \meta{tl var_2} \Arg{false code}
\cs{tlVarIfEqTF} \meta{tl var_1} \meta{tl var_2} \Arg{true code} \Arg{false code}
\end{syntax}
Compares the content of two \meta{token list variables} and
is logically \texttt{true} if the two contain the same list of
tokens (\emph{i.e.}~identical in both the list of characters they
contain and the category codes of those characters). For example
\begin{demohigh}
\tlSet \lTmpaTl {abc}
\tlSet \lTmpbTl {abc}
\tlSet \lTmpcTl {xyz}
\tlVarIfEqTF \lTmpaTl \lTmpbTl {\prgReturn{Yes}} {\prgReturn{No}}
\tlVarIfEqTF \lTmpaTl \lTmpcTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
See also \cs{strVarIfEq} for a comparison that ignores category codes.
\end{function}

\begin{function}{\tlIfIn,\tlIfInT,\tlIfInF,\tlIfInTF}
\begin{syntax}
\cs{tlIfIn} \Arg{token list_1} \Arg{token list_2}
\cs{tlIfInT} \Arg{token list_1} \Arg{token list_2} \Arg{true code}
\cs{tlIfInF} \Arg{token list_1} \Arg{token list_2} \Arg{false code}
\cs{tlIfInTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if \meta{token list_2} is found inside \meta{token list_1}.
The \meta{token list_2} cannot contain the tokens \verb|{|, \verb|}| or \verb|#|
(more precisely, explicit character tokens with category code $1$
(begin-group) or $2$ (end-group), and tokens with category code $6$).
The search does \emph{not} enter brace (category code $1$/$2$) groups.
\begin{demohigh}
\tlIfInTF {hello world} {o} {\prgReturn{Yes}} {\prgReturn{No}}
\tlIfInTF {hello world} {a} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\tlVarIfIn,\tlVarIfInT,\tlVarIfInF,\tlVarIfInTF}
\begin{syntax}
\cs{tlVarIfIn} \meta{tl var} \Arg{token list}
\cs{tlVarIfInT} \meta{tl var} \Arg{token list} \Arg{true code}
\cs{tlVarIfInF} \meta{tl var} \Arg{token list} \Arg{false code}
\cs{tlVarIfInTF} \meta{tl var} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{token list} is found in the content of the
\meta{tl var}. The \meta{token list} cannot contain
the tokens \verb|{|, \verb|}| or \verb|#|
(more precisely, explicit character tokens with category code $1$
(begin-group) or $2$ (end-group), and tokens with category code $6$).
\begin{demohigh}
\tlSet \lTmpaTl {hello world}
\tlVarIfInTF \lTmpaTl {o} {\prgReturn{Yes}} {\prgReturn{No}}
\tlVarIfInTF \lTmpaTl {a} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\tlIfSingle,\tlIfSingleT,\tlIfSingleF,\tlIfSingleTF}
\begin{syntax}
\cs{tlIfSingle} \Arg{token list}
\cs{tlIfSingleT} \Arg{token list} \Arg{true code}
\cs{tlIfSingleF} \Arg{token list} \Arg{false code}
\cs{tlIfSingleTF} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{token list} has exactly one \meta{item}, \emph{i.e.} is
a single normal token (neither an explicit space character nor a
begin-group character) or a single brace group, surrounded by
optional spaces on both sides. In other words, such a token list has
token count $1$ according to \cs{tlCount}.
\begin{demohigh}
\tlIfSingleTF {a} {\prgReturn{Yes}} {\prgReturn{No}}
\tlIfSingleTF {abc} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\tlVarIfSingle,\tlVarIfSingleT,\tlVarIfSingleF,\tlVarIfSingleTF}
\begin{syntax}
\cs{tlVarIfSingle} \meta{tl var}
\cs{tlVarIfSingleT} \meta{tl var} \Arg{true code}
\cs{tlVarIfSingleF} \meta{tl var} \Arg{false code}
\cs{tlVarIfSingleTF} \meta{tl var} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the content of the \meta{tl var} consists of a single \meta{item},
\emph{i.e.} is a single normal token (neither an explicit space
character nor a begin-group character) or a single brace group,
surrounded by optional spaces on both sides. In other words, such a
token list has token count $1$ according to \cs{tlVarCount}.
\begin{demohigh}
\tlSet \lTmpaTl {a}
\tlVarIfSingleTF \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\tlSet \lTmpaTl {abc}
\tlVarIfSingleTF \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\section{Token List Case Functions}

\begin{function}{\tlVarCase}
\begin{syntax}
\cs{tlVarCase} \meta{test token list variable}
~ ~ \verb"{"
~ ~ ~ ~ \meta{token list variable case_1} \Arg{code case_1}
~ ~ ~ ~ \meta{token list variable case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \meta{token list variable case_n} \Arg{code case_n}
~ ~ \verb"}"
\end{syntax}
This function compares the \meta{test token list variable} in turn
with each of the \meta{token list variable cases}. If the two
are equal (as described for \cs{tlVarIfEq})
then the associated \meta{code} is left in the input
stream and other cases are discarded. The function
does nothing if there is no match.
\begin{demohigh}
\IgnoreSpacesOn
\tlSet \lTmpaTl {a}
\tlSet \lTmpbTl {b}
\tlSet \lTmpcTl {c}
\tlSet \lTmpkTl {b}
\tlVarCase \lTmpkTl {
  \lTmpaTl {\prgReturn {First}}
  \lTmpbTl {\prgReturn {Second}}
  \lTmpcTl {\prgReturn {Third}}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\tlVarCaseT}
\begin{syntax}
\cs{tlVarCaseT} \meta{test token list variable}
~ ~ \verb"{"
~ ~ ~ ~ \meta{token list variable case_1} \Arg{code case_1}
~ ~ ~ ~ \meta{token list variable case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \meta{token list variable case_n} \Arg{code case_n}
~ ~ \verb"}"
~ ~ \Arg{true code}
\end{syntax}
This function compares the \meta{test token list variable} in turn
with each of the \meta{token list variable cases}. If the two
are equal (as described for \cs{tlVarIfEq})
then the associated \meta{code} is left in the input
stream and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case).
\begin{demohigh}
\IgnoreSpacesOn
\tlSet \lTmpaTl {a}
\tlSet \lTmpbTl {b}
\tlSet \lTmpcTl {c}
\tlSet \lTmpkTl {b}
\tlVarCaseT \lTmpkTl {
  \lTmpaTl {\intSet \lTmpkInt {1}}
  \lTmpbTl {\intSet \lTmpkInt {2}}
  \lTmpcTl {\intSet \lTmpkInt {3}}
}{
  \prgReturn {\intUse \lTmpkInt}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\tlVarCaseF}
\begin{syntax}
\cs{tlVarCaseF} \meta{test token list variable}
~ ~ \verb"{"
~ ~ ~ ~ \meta{token list variable case_1} \Arg{code case_1}
~ ~ ~ ~ \meta{token list variable case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \meta{token list variable case_n} \Arg{code case_n}
~ ~ \verb"}"
~ ~ \Arg{false code}
\end{syntax}
This function compares the \meta{test token list variable} in turn
with each of the \meta{token list variable cases}. If the two
are equal (as described for \cs{tlVarIfEq})
then the associated \meta{code} is left in the input
stream and other cases are discarded. If none match then the \meta{false code}
is inserted into the input stream (after the code for the appropriate case).
\begin{demohigh}
\IgnoreSpacesOn
\tlSet \lTmpaTl {a}
\tlSet \lTmpbTl {b}
\tlSet \lTmpcTl {c}
\tlSet \lTmpkTl {b}
\tlVarCaseF \lTmpkTl{
  \lTmpaTl {\prgReturn {First}}
  \lTmpbTl {\prgReturn {Second}}
  \lTmpcTl {\prgReturn {Third}}
}{
  \prgReturn {No~Match!}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\tlVarCaseTF}
\begin{syntax}
\cs{tlVarCaseTF} \meta{test token list variable}
~ ~ \verb"{"
~ ~ ~ ~ \meta{token list variable case_1} \Arg{code case_1}
~ ~ ~ ~ \meta{token list variable case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \meta{token list variable case_n} \Arg{code case_n}
~ ~ \verb"}"
~ ~ \Arg{true code}
~ ~ \Arg{false code}
\end{syntax}
This function compares the \meta{test token list variable} in turn
with each of the \meta{token list variable cases}. If the two
are equal (as described for \cs{tlVarIfEq})
then the associated \meta{code} is left in the input
stream and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case), while if none
match then the \meta{false code} is inserted. The function \cs{tlVarCase},
which does nothing if there is no match, is also available.
\begin{demohigh}
\IgnoreSpacesOn
\tlSet \lTmpaTl {a}
\tlSet \lTmpbTl {b}
\tlSet \lTmpcTl {c}
\tlSet \lTmpkTl {b}
\tlVarCaseTF \lTmpkTl {
  \lTmpaTl {\intSet \lTmpkInt {1}}
  \lTmpbTl {\intSet \lTmpkInt {2}}
  \lTmpcTl {\intSet \lTmpkInt {3}}
}{
  \prgReturn {\intUse \lTmpkInt}
}{
  \prgReturn {0}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\chapter{Strings (\texttt{Str})}

\TeX{} associates each character with a category code: as such, there is no
concept of a \enquote{string} as commonly understood in many other
programming languages. However, there are places where we wish to manipulate
token lists while in some sense \enquote{ignoring} category codes: this is
done by treating token lists as strings in a \TeX{} sense.

A \TeX{} string (and thus an \pkg{expl3} string) is a series of characters
which have category code $12$ (\enquote{other}) with the exception of
space characters which have category code $10$ (\enquote{space}). Thus
at a technical level, a \TeX{} string is a token list with the appropriate
category codes. In this documentation, these are simply referred to as
strings.

String variables are simply specialised token lists, but by convention
should be named with the suffix \texttt{Str}.  Such variables
should contain characters with category code $12$ (other), except
spaces, which have category code $10$ (blank space).  All the
functions in this module which accept a token list argument first
convert it to a string using \cs{tlToStr} for internal processing,
and do not treat a token list or the corresponding string
representation differently.

As a string is a subset of the more general token list, it is sometimes unclear
when one should be used over the other.
Use a string variable for data that isn't primarily intended for typesetting
and for which a level of protection from unwanted expansion is suitable.
This data type simplifies comparison of variables since there are no concerns
about expansion of their contents.

%The functions \cs{CsToStr}, \cs{tlToStr}, \cs{tlVarToStr} and
%\cs{TokenToStr} (and variants) generate strings from the appropriate
%input: these are documented in modules \pkg{Cs}, \pkg{Tl} and \pkg{Token},
%respectively.

\section{Constant and Scratch Strings}

\begin{variable}{\cAmpersandStr,\cAtsignStr,\cBackslashStr,\cLeftBraceStr,\cRightBraceStr,
\cCircumflexStr,\cColonStr,\cDollarStr,\cHashStr,\cPercentStr,\cTildeStr,\cUnderscoreStr,\cZeroStr}
Constant strings, containing a single character token, with category code $12$.
\end{variable}

\begin{variable}{\lTmpaStr,\lTmpbStr,\lTmpcStr,\lTmpiStr,\lTmpjStr,\lTmpkStr}
Scratch strings for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaStr,\gTmpbStr,\gTmpcStr,\gTmpiStr,\gTmpjStr,\gTmpkStr}
Scratch strings for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Creating and Using Strings}

\begin{function}{\strNew}
\begin{syntax}
\cs{strNew} \meta{str var}
\end{syntax}
Creates a new \meta{str var} or raises an error if the name is
already taken. The declaration is global. The \meta{str var} is
initially empty.
\begin{codehigh}
\strNew \lFooSomeStr
\end{codehigh}
\end{function}

\begin{function}{\strConst}
\begin{syntax}
\cs{strConst} \meta{str var} \Arg{token list}
\end{syntax}
Creates a new constant \meta{str var} or raises an error if the name
is already taken.  The value of the \meta{str var} is set
globally to the \meta{token list}, converted to a string.
\begin{codehigh}
\strConst \cFooSomeStr {12\abc34}
\end{codehigh}
\end{function}

\begin{function}{\strUse}
\begin{syntax}
\cs{strUse} \meta{str var}
\end{syntax}
Recovers the content of a \meta{str var} and returns the value.
An error is raised if the variable
does not exist or if it is invalid. Note that it is possible to use
a \meta{str} directly without an accessor function.
\begin{codehigh}
\strUse \lTmpaStr
\end{codehigh}
\end{function}

\section{Viewing Strings}

\begin{function}{\strLog}
\begin{syntax}
\cs{strLog} \Arg{token list}
\end{syntax}
Writes \meta{token list} in the log file.
\begin{codehigh}
\strLog {1234\abcd5678}
\end{codehigh}
\end{function}

\begin{function}{\strVarLog}
\begin{syntax}
\cs{strVarLog} \meta{str var}
\end{syntax}
Writes the content of the \meta{str var} in the log file.
\begin{codehigh}
\strSet \lTmpiStr {1234\abcd5678}
\strVarLog \lTmpiStr
\end{codehigh}
\end{function}

\begin{function}{\strShow}
\begin{syntax}
\cs{strShow} \Arg{token list}
\end{syntax}
Displays \meta{token list} on the terminal.
\begin{codehigh}
\strShow {1234\abcd5678}
\end{codehigh}
\end{function}

\begin{function}{\strVarShow}
\begin{syntax}
\cs{strVarShow} \meta{str var}
\end{syntax}
Displays the content of the \meta{str var} on the terminal.
\begin{codehigh}
\strSet \lTmpiStr {1234\abcd5678}
\strVarShow \lTmpiStr
\end{codehigh}
\end{function}

\section{Setting String Variables}

\begin{function}{\strSet}
\begin{syntax}
\cs{strSet} \meta{str var} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string}, and stores the
result in \meta{str var}.
\begin{demohigh}
\strSet \lTmpiStr {\intMathMult{4}{5}}
\strUse \lTmpiStr
\end{demohigh}
\end{function}

\begin{function}{\strSetEq}
\begin{syntax}
\cs{strSetEq} \meta{str var_1} \meta{str var_2}
\end{syntax}
Sets the content of \meta{str var_1} equal to that of \meta{str var_2}.
\begin{demohigh}
\strSet \lTmpaStr {abc}
\strSetEq \lTmpbStr \lTmpaStr
\strUse \lTmpbStr
\end{demohigh}
\end{function}

\begin{function}{\strClear}
\begin{syntax}
\cs{strClear} \meta{str var}
\end{syntax}
Clears the content of the \meta{str var}. For example
\begin{demohigh}
\strSet \lTmpjStr {One}
\strClear \lTmpjStr
\strSet \lTmpjStr {Two}
\strUse \lTmpjStr
\end{demohigh}
\end{function}

\begin{function}{\strClearNew}
\begin{syntax}
\cs{strClearNew} \meta{str var}
\end{syntax}
Ensures that the \meta{str var} exists globally by applying
\cs{strNew} if necessary, then applies \cs{strClear} to leave
the \meta{str var} empty.
\begin{codehigh}
\strClearNew \lFooSomeStr
\strUse \lFooSomeStr
\end{codehigh}
\end{function}

\begin{function}{\strConcat}
\begin{syntax}
\cs{strConcat} \meta{str var_1} \meta{str var_2} \meta{str var_3}
\end{syntax}
Concatenates the content of \meta{str var_2} and \meta{str var_3}
together and saves the result in \meta{str var_1}. The \meta{str var_2}
is placed at the left side of the new string variable.
The \meta{str var_2} and \meta{str var_3} must indeed be strings, as
this function does not convert their contents to a string.
\begin{demohigh}
\strSet \lTmpbStr {con}
\strSet \lTmpcStr {cat}
\strConcat \lTmpaStr \lTmpbStr \lTmpcStr
\strUse \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strPutLeft}
\begin{syntax}
\cs{strPutLeft} \meta{str var} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string}, and prepends the
result to \meta{str var}.  The current contents of the \meta{str
var} are not automatically converted to a string.
\begin{demohigh}
\strSet \lTmpkStr {Functional}
\strPutLeft \lTmpkStr {Hello}
\strUse \lTmpkStr
\end{demohigh}
\end{function}

\begin{function}{\strPutRight}
\begin{syntax}
\cs{strPutRight} \meta{str var} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string}, and appends the
result to \meta{str var}.  The current contents of the \meta{str
var} are not automatically converted to a string.
\begin{demohigh}
\strSet \lTmpkStr {Functional}
\strPutRight \lTmpkStr {World}
\strUse \lTmpkStr
\end{demohigh}
\end{function}

\section{Modifying String Variables}

\begin{function}{\strVarReplaceOnce}
\begin{syntax}
\cs{strVarReplaceOnce} \meta{str var} \Arg{old} \Arg{new}
\end{syntax}
Converts the \meta{old} and \meta{new} token lists to strings, then
replaces the first (leftmost) occurrence of \meta{old string} in the
\meta{str var} with \meta{new string}.
\begin{demohigh}
\strSet \lTmpaStr {a{bc}bcd}
\strVarReplaceOnce \lTmpaStr {bc} {xx}
\strUse \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strVarReplaceAll}
\begin{syntax}
\cs{strVarReplaceAll} \meta{str var} \Arg{old} \Arg{new}
\end{syntax}
Converts the \meta{old} and \meta{new} token lists to strings, then
replaces all occurrences of \meta{old string} in the
\meta{str var} with \meta{new string}.
As this function
operates from left to right, the pattern \meta{old string}
may remain after the replacement.
\begin{demohigh}
\strSet \lTmpaStr {a{bc}bcd}
\strVarReplaceAll \lTmpaStr {bc} {xx}
\strUse \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strVarRemoveOnce}
\begin{syntax}
\cs{strVarRemoveOnce} \meta{str var} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string} then
removes the first (leftmost) occurrence of \meta{string} from the \meta{str var}.
\begin{demohigh}
\strSet \lTmpaStr {a{bc}bcd}
\strVarRemoveOnce \lTmpaStr {bc}
\strUse \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strVarRemoveAll}
\begin{syntax}
\cs{strVarRemoveAll} \meta{str var} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string} then
removes all occurrences of \meta{string} from the \meta{str var}.
As this function operates from left to right,
the pattern \meta{string} may remain after the removal, for instance,
\begin{demohigh}
\strSet \lTmpaStr {abbccd}
\strVarRemoveAll \lTmpaStr {bc}
\tlUse \lTmpaStr
\end{demohigh}
\end{function}

\section{Working with the Content of Strings}

\begin{function}{\strCount}
\begin{syntax}
\cs{strCount} \Arg{token list}
\end{syntax}
Returns the number of characters in the string representation of \meta{token list},
as an integer denotation. All characters including spaces are counted.
\begin{demohigh}
\strCount {12\abc34}
\end{demohigh}
\end{function}

\begin{function}{\StVarCount}
\begin{syntax}
\cs{strVarCount} \meta{tl var}
\end{syntax}
Returns the number of characters in the string representation of the \meta{tl var},
as an integer denotation. All characters including spaces are counted.
\begin{demohigh}
\strSet \lTmpaStr {12\abc34}
\strVarCount \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strHead}
\begin{syntax}
\cs{strHead} \Arg{token list}
\end{syntax}
Converts the \meta{token list} into a \meta{string}.
The first character in the \meta{string} is then returned,
with category code \enquote{other}. If the first character is a space,
it returns a space token with category code $10$ (blank space).
If the \meta{string} is empty, then nothing is returned.
\begin{demohigh}
\strHead {HELLO}
\end{demohigh}
\end{function}

\begin{function}{\strVarHead}
\begin{syntax}
\cs{strVarHead} \meta{tl var}
\end{syntax}
Converts the \meta{tl var} into a \meta{string}.
The first character in the \meta{string} is then returned,
with category code \enquote{other}. If the first character is a space,
it returns a space token with category code $10$ (blank space).
If the \meta{string} is empty, then nothing is returned.
\begin{demohigh}
\strSet \lTmpaStr {HELLO}
\strVarHead \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strTail}
\begin{syntax}
\cs{strTail} \Arg{token list}
\end{syntax}
Converts the \meta{token list} to a \meta{string}, removes the first
character, and returns the remaining characters (if any)
with category codes $12$ and $10$ (for spaces).
If the first character is a space, it only trims that space.
If the \meta{token list} is empty,
then nothing is left on the input stream.
\begin{demohigh}
\strTail {HELLO}
\end{demohigh}
\end{function}

\begin{function}{\strVarTail}
\begin{syntax}
\cs{strVarTail} \meta{tl var}
\end{syntax}
Converts the \meta{tl var} to a \meta{string}, removes the first
character, and returns the remaining characters (if any)
with category codes $12$ and $10$ (for spaces).
If the first character is a space, it only trims that space.
If the \meta{token list} is empty,
then nothing is left on the input stream.
\begin{demohigh}
\strSet \lTmpaStr {HELLO}
\strVarTail \lTmpaStr
\end{demohigh}
\end{function}

\begin{function}{\strItem}
\begin{syntax}
\cs{strItem} \Arg{token list} \Arg{integer expression}
\end{syntax}
Converts the \meta{token list} to a \meta{string},
and returns the character in position \meta{integer expression} of
the \meta{string}, starting at $1$ for the first (left-most)
character. All characters including spaces are taken into account.
If the \meta{integer expression} is negative,
characters are counted from the end of the \meta{string}. Hence,
$-1$ is the right-most character, \emph{etc.}
\begin{demohigh}
\strItem {abcd} {3}
\end{demohigh}
\end{function}

\begin{function}{\strVarItem}
\begin{syntax}
\cs{strVarItem} \meta{tl var} \Arg{integer expression}
\end{syntax}
Converts the \meta{tl var} to a \meta{string},
and returns the character in position \meta{integer expression} of
the \meta{string}, starting at $1$ for the first (left-most)
character. All characters including spaces are taken into account.
If the \meta{integer expression} is negative,
characters are counted from the end of the \meta{string}. Hence,
$-1$ is the right-most character, \emph{etc.}
\begin{demohigh}
\strSet \lTmpaStr {abcd}
\strVarItem \lTmpaStr {3}
\end{demohigh}
\end{function}

\section{Mapping over Strings}

%All mappings are done at the current group level, \emph{i.e.} any
%local assignments made by the \meta{function} or \meta{code} discussed
%below remain in effect after the loop.

%\begin{function}{\strMapFunction,\strVarMapFunction}
%\begin{syntax}
%\cs{strMapFunction} \Arg{token list} \meta{function}
%\cs{strVarMapFunction} \meta{str var} \meta{function}
%\end{syntax}
%Converts the \meta{token list} to a \meta{string} then
%applies \meta{function} to every \meta{character} in the
%\meta{string} including spaces.
%\end{function}

\begin{function}{\strMapInline,\strVarMapInline}
\begin{syntax}
\cs{strMapInline} \Arg{token list} \Arg{inline function}
\cs{strVarMapInline} \meta{str var} \Arg{inline function}
\end{syntax}
Converts the \meta{token list} to a \meta{string} then
applies the \meta{inline function} to every \meta{character} in the
\meta{str var} including spaces.
The \meta{inline function} should consist of code which
receives the \meta{character} as \verb|#1|.
\begin{demohigh}
\IgnoreSpacesOn
\strClear \lTmpaStr
\strMapInline {one} {
  \strPutRight \lTmpaStr {[#1]}
}
\strUse \lTmpaStr
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\strMapTokens, \strVarMapTokens}
%\begin{syntax}
%\cs{strMapTokens} \Arg{token list} \Arg{code}
%\cs{strVarMapTokens} \meta{str var} \Arg{code}
%\end{syntax}
%Converts the \meta{token list} to a \meta{string} then applies
%\meta{code} to every \meta{character} in the \meta{string} including spaces.
%The \meta{code} receives each character as a trailing brace group.
%This is equivalent to \cs{strMapFunction} if the
%\meta{code} consists of a single function.
%\end{function}

\begin{function}{\strMapVariable,\strMapVariable}
\begin{syntax}
\cs{strMapVariable} \Arg{token list} \meta{variable} \Arg{code}
\cs{strVarMapVariable} \meta{str var} \meta{variable} \Arg{code}
\end{syntax}
Converts the \meta{token list} to a \meta{string} then stores each
\meta{character} in the \meta{string} (including spaces) in turn in
the (string or token list) \meta{variable} and applies the
\meta{code}.  The \meta{code} will usually make use of the
\meta{variable}, but this is not enforced.  The assignments to the
\meta{variable} are local.  Its value after the loop is the last
\meta{character} in the \meta{string}, or its original value if the
\meta{string} is empty.
\begin{demohigh}
\IgnoreSpacesOn
\strClear \lTmpaStr
\strMapVariable {one} \lTmpiStr {
  \strPutRight \lTmpaStr {\expWhole {[\lTmpiStr]}}
}
\strUse \lTmpaStr
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\strMapBreak}
%\begin{syntax}
%\cs{strMapBreak}
%\end{syntax}
%Used to terminate a string map function before all
%characters in the \meta{string} have been processed. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\str_map_inline:Nn \l_my_str
%{
%\str_if_eq:nnT { #1 } { bingo } { \str_map_break: }
%Do something useful
%}
%\end{verbatim}
%See also \cs{strMapBreakDo}.
%Use outside of a string map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before continuing with the
%code that follows the loop.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}
%
%\begin{function}{\strMapBreakDo}
%\begin{syntax}
%\cs{strMapBreakDo} \Arg{code}
%\end{syntax}
%Used to terminate a string map function before all
%characters in the \meta{string} have been processed, inserting
%the \meta{code} after the mapping has ended. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\str_map_inline:Nn \l_my_str
%{
%\str_if_eq:nnT { #1 } { bingo }
%{ \str_map_break:n { <code> } }
%Do something useful
%}
%\end{verbatim}
%Use outside of a string map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before the \meta{code} is
%inserted into the input stream.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}

\section{String Conditionals}

\begin{function}{\strIfExist,\strIfExistT,\strIfExistF,\strIfExistTF}
\begin{syntax}
\cs{strIfExist} \meta{str var}
\cs{strIfExistT} \meta{str var} \Arg{true code}
\cs{strIfExistF} \meta{str var} \Arg{false code}
\cs{strIfExistTF} \meta{str var} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{str var} is currently defined.  This does not
check that the \meta{str var} really is a string.
\begin{demohigh}
\strIfExistTF \lTmpaStr {\prgReturn{Yes}} {\prgReturn{No}}
\strIfExistTF \lFooUndefinedStr {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\strVarIfEmpty,\strVarIfEmptyT,\strVarIfEmptyF,\strVarIfEmptyTF}
\begin{syntax}
\cs{strVarIfEmpty} \meta{str var}
\cs{strVarIfEmptyT} \meta{str var} \Arg{true code}
\cs{strVarIfEmptyF} \meta{str var} \Arg{false code}
\cs{strVarIfEmptyTF} \meta{str var} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{string variable} is entirely empty
(\emph{i.e.} contains no characters at all).
\begin{demohigh}
\strSet \lTmpaStr {abc}
\strVarIfEmptyTF \lTmpaStr {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\strClear \lTmpaStr
\strVarIfEmptyTF \lTmpaStr {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\strIfEq,\strIfEqT,\strIfEqF,\strIfEqTF}
\begin{syntax}
\cs{strIfEq} \Arg{tl_1} \Arg{tl_2}
\cs{strIfEqT} \Arg{tl_1} \Arg{tl_2} \Arg{true code}
\cs{strIfEqF} \Arg{tl_1} \Arg{tl_2} \Arg{false code}
\cs{strIfEqTF} \Arg{tl_1} \Arg{tl_2} \Arg{true code} \Arg{false code}
\end{syntax}
Compares the two \meta{token lists} on a character by character
basis (namely after converting them to strings),
and is \texttt{true} if the two \meta{strings} contain the same
characters in the same order.
%Thus for example
%\begin{codehigh}
%\strIfEq{abc}{\tlToStr{abc}}
%\end{codehigh}
%is logically \texttt{true}.
See \cs{tlIfEq} to compare
tokens (including their category codes) rather than characters.
For example
\begin{demohigh}
\strIfEqTF {abc} {abc} {\prgReturn{Yes}} {\prgReturn{No}}
\strIfEqTF {abc} {xyz} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
%\begin{demohigh}
%\strSet\lTmpaStr{abc}
%\strSet\lTmpbStr{abc}
%\strSet\lTmpcStr{xyz}
%\strIfEqTF{\lTmpaStr}{\lTmpbStr}{\prgReturn{Yes}}{\prgReturn{No}}
%\strIfEqTF{\lTmpaStr}{\lTmpcStr}{\prgReturn{Yes}}{\prgReturn{No}}
%\strIfEqTF{\strUse\lTmpaStr}{\strUse\lTmpbStr}{\prgReturn{Yes}}{\prgReturn{No}}
%\strIfEqTF{\strUse\lTmpaStr}{\strUse\lTmpcStr}{\prgReturn{Yes}}{\prgReturn{No}}
%\end{demohigh}
\end{function}

\begin{function}{\strVarIfEq,\strVarIfEqT,\strVarIfEqF,\strVarIfEqTF}
\begin{syntax}
\cs{strVarIfEq} \meta{str var_1} \meta{str var_2}
\cs{strVarIfEqT} \meta{str var_1} \meta{str var_2} \Arg{true code}
\cs{strVarIfEqF} \meta{str var_1} \meta{str var_2} \Arg{false code}
\cs{strVarIfEqTF} \meta{str var_1} \meta{str var_2} \Arg{true code} \Arg{false code}
\end{syntax}
Compares the content of two \meta{str variables} and
is logically \texttt{true} if the two contain the same characters
in the same order.  See \cs{tlVarIfEq} to compare tokens
(including their category codes) rather than characters.
\begin{demohigh}
\strSet \lTmpaStr {abc}
\strSet \lTmpbStr {abc}
\strSet \lTmpcStr {xyz}
\strVarIfEqTF \lTmpaStr \lTmpbStr {\prgReturn{Yes}} {\prgReturn{No}}
\strVarIfEqTF \lTmpaStr \lTmpcStr {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\strIfIn,\strIfInT,\strIfInF,\strIfInTF}
\begin{syntax}
\cs{strIfIn} \Arg{tl_1} \Arg{tl_2}
\cs{strIfInT} \Arg{tl_1} \Arg{tl_2} \Arg{true code}
\cs{strIfInF} \Arg{tl_1} \Arg{tl_2} \Arg{false code}
\cs{strIfInTF} \Arg{tl_1} \Arg{tl_2} \Arg{true code} \Arg{false code}
\end{syntax}
Converts both \meta{token lists} to \meta{strings} and
tests whether \meta{string_2} is found inside \meta{string_1}.
\begin{demohigh}
\strIfInTF {hello world} {o} {\prgReturn{Yes}}{\prgReturn{No}}
\strIfInTF {hello world} {a} {\prgReturn{Yes}}{\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\strVarIfIn,\strVarIfInT,\strVarIfInF,\strVarIfInTF}
\begin{syntax}
\cs{strVarIfIn} \meta{str var} \Arg{token list}
\cs{strVarIfInT} \meta{str var} \Arg{token list} \Arg{true code}
\cs{strVarIfInF} \meta{str var} \Arg{token list} \Arg{false code}
\cs{strVarIfInTF} \meta{str var} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Converts the \meta{token list} to a \meta{string} and
tests if that \meta{string} is found in the content of the \meta{str var}.
\begin{demohigh}
\strSet \lTmpaStr {hello world}
\strVarIfInTF \lTmpaStr {o} {\prgReturn{Yes}}{\prgReturn{No}}
\strVarIfInTF \lTmpaStr {a} {\prgReturn{Yes}}{\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\strCompare,\strCompareT,\strCompareF,\strCompareTF}
\begin{syntax}
\cs{strCompare} \Arg{tl_1} \meta{relation} \Arg{tl_2}
\cs{strCompareT} \Arg{tl_1} \meta{relation} \Arg{tl_2} \Arg{true code}
\cs{strCompareF} \Arg{tl_1} \meta{relation} \Arg{tl_2} \Arg{false code}
\cs{strCompareTF} \Arg{tl_1} \meta{relation} \Arg{tl_2} \Arg{true code} \Arg{false code}
\end{syntax}
Compares the two \meta{token lists} on a character by character
basis (namely after converting them to strings) in a lexicographic
order according to the character codes of the characters.  The
\meta{relation} can be \verb|<|, \verb|=|, or \verb|>| and the test is
\texttt{true} under the following conditions:
\begin{itemize}[nosep]
\item for \verb|<|, if the first string is earlier than the second in lexicographic order;
\item for \verb|=|, if the two strings have exactly the same characters;
\item for \verb|>|, if the first string is later than the second in lexicographic order.
\end{itemize}
For example:
\begin{demohigh}
\strCompareTF {ab} < {abc} {\prgReturn{Yes}} {\prgReturn{No}}
\strCompareTF {ab} < {aa} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
%\begin{texnote}
%This is a wrapper around the \TeX{} primitive
%\cs{(pdf)strcmp}.  It is meant for programming
%and not for sorting textual contents, as it simply considers
%character codes and not more elaborate considerations of grapheme
%clusters, locale, etc.
%\end{texnote}
\end{function}

\section{String Case Functions}

\begin{function}{\strCase}
\begin{syntax}
\cs{strCase} \Arg{test string}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{string case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{string case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{string case_n} \Arg{code case_n}
~ ~ \verb|}|
\end{syntax}
Compares the \meta{test string} in turn with each
of the \meta{string cases} (all token lists are converted to strings).
If the two are equal (as described for
\cs{strIfEq}) then the associated \meta{code} is left in the
input stream and other cases are discarded.
\begin{demohigh}
\IgnoreSpacesOn
\strCase {bbb} {
  {aaa} {\prgReturn{First}}
  {bbb} {\prgReturn{Second}}
  {ccb} {\prgReturn{Third}}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\strCaseT}
\begin{syntax}
\cs{strCaseT} \Arg{test string}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{string case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{string case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{string case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{true code}
\end{syntax}
Compares the \meta{test string} in turn with each
of the \meta{string cases} (all token lists are converted to strings).
If the two are equal (as described for
\cs{strIfEq}) then the associated \meta{code} is left in the
input stream and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case).
\begin{demohigh}
\IgnoreSpacesOn
\strCaseT {bbb} {
  {aaa} {\tlSet\lTmpkTl{First}}
  {bbb} {\tlSet\lTmpkTl{Second}}
  {ccb} {\tlSet\lTmpkTl{Third}}
}{
  \prgReturn{\tlUse\lTmpkTl}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\strCaseF}
\begin{syntax}
\cs{strCaseF} \Arg{test string}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{string case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{string case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{string case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{false code}
\end{syntax}
Compares the \meta{test string} in turn with each
of the \meta{string cases} (all token lists are converted to strings).
If the two are equal (as described for
\cs{strIfEq}) then the associated \meta{code} is left in the
input stream and other cases are discarded. If none
match then the \meta{false code} is inserted.
\begin{demohigh}
\IgnoreSpacesOn
\strCaseF {bbb} {
  {aaa} {\prgReturn{First}}
  {bbb} {\prgReturn{Second}}
  {ccb} {\prgReturn{Third}}
}{
  \prgReturn{No~Match!}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\strCaseTF}
\begin{syntax}
\cs{strCaseTF} \Arg{test string}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{string case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{string case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{string case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{true code}
~ ~ \Arg{false code}
\end{syntax}
Compares the \meta{test string} in turn with each
of the \meta{string cases} (all token lists are converted to strings).
If the two are equal (as described for
\cs{strIfEq}) then the associated \meta{code} is left in the
input stream and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case), while if none
match then the \meta{false code} is inserted.
\begin{demohigh}
\IgnoreSpacesOn
\strCaseTF {bbb} {
  {aaa} {\tlSet\lTmpkTl{First}}
  {bbb} {\tlSet\lTmpkTl{Second}}
  {ccb} {\tlSet\lTmpkTl{Third}}
}{
  \prgReturn{\tlUse\lTmpkTl}
}{
  \prgReturn{No~Match!}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\chapter{Integers (\texttt{Int})}

\section{Constant and Scratch Integers}

\begin{variable}{\cZeroInt,\cOneInt}
Integer values used with primitive tests and assignments: their
self-terminating nature makes these more convenient and faster than
literal numbers.
\end{variable}

\begin{variable}{\cMaxInt}
The maximum value that can be stored as an integer.
\end{variable}

\begin{variable}{\cMaxRegisterInt}
Maximum number of registers.
\end{variable}

\begin{variable}{\cMaxCharInt}
Maximum character code completely supported by the engine.
\end{variable}

\begin{variable}{\lTmpaInt,\lTmpbInt,\lTmpcInt,\lTmpiInt,\lTmpjInt,\lTmpkInt}
Scratch integer for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaInt,\gTmpbInt,\gTmpcInt,\gTmpiInt,\gTmpjInt,\gTmpkInt}
Scratch integer for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{The Syntax of Integer Expressions}

An \meta{integer expression} should consist,
after evaluation of functions defined with \cs{PrgNewFunction}
and expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/},
\texttt{(}, \texttt{)} and of course integer operands.  The result
is calculated by applying standard mathematical rules with the
following peculiarities:
\begin{itemize}
\item \texttt{/} denotes division rounded to the closest integer with
ties rounded away from zero;
\item there is an error and the overall expression evaluates to zero
whenever the absolute value of any intermediate result exceeds
$2^{31}-1$, except in the case of scaling operations
$a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be
arbitrarily large (but the operands $a$, $b$, $c$ are still
constrained to an absolute value at most $2^{31}-1$);
\item parentheses may not appear after unary \texttt{+} or
\texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start
of an expression or after \texttt{+}, \texttt{-}, \texttt{*},
\texttt{/} or~\texttt{(} leads to an error.
\end{itemize}
Each integer operand can be either an integer variable (with no need
for \cs{intUse}) or an integer denotation.
For example both of the following give the same result
because \cs{lFooSomeTl} expands to the integer denotation~$5$
while the integer variable \cs{lFooSomeInt} takes the value~$4$.
\begin{demohigh}
\intEval {5 +  4 * 3 - (3 + 4 * 5)}
\end{demohigh}
\begin{demohigh}
\tlNew \lFooSomeTl
\tlSet \lFooSomeTl {5}
\intNew \lFooSomeInt
\intSet \lFooSomeInt {4}
\intEval {\lFooSomeTl +  \lFooSomeInt * 3 - (3 + 4 * 5)}
\end{demohigh}

%\begin{texnote}
%As all \TeX{} integers, integer operands can also be:
%\tn{value}\Arg{\LaTeXe{} counter}; dimension or skip variables,
%converted to integers in~\texttt{sp}; the character code of some
%character given as \texttt{`}\meta{char} or
%\texttt{`\textbackslash}\meta{char}; octal numbers given as
%\texttt{'} followed by digits from \texttt{0} to \texttt{7}; or
%hexadecimal numbers given as \verb|"| followed by digits and upper case
%letters from \texttt{A} to~\texttt{F}.
%\end{texnote}

\section{Using Integer Expressions}

\begin{function}{\intEval}
\begin{syntax}
\cs{intEval} \Arg{integer expression}
\end{syntax}
Evaluates the \meta{integer expression} and returns the result:
for positive results an
explicit sequence of decimal digits not starting with~\texttt{0},
for negative results \texttt{-}~followed by such a sequence, and
\texttt{0}~for zero. For example
\begin{demohigh}
\intEval {(1+4)*(2-3)/5}
\end{demohigh}
\begin{demohigh}
\intEval {\strCount{12\TeX34} - \tlCount{12\TeX34}}
\end{demohigh}
\end{function}

\begin{function}{\intMathAdd}
\begin{syntax}
\cs{intMathAdd} \Arg{integer expression_1} \Arg{integer expression_2}
\end{syntax}
Adds \Arg{integer expression_1} and \Arg{integer expression_2},
and returns the result. For example
\begin{demohigh}
\intMathAdd {7} {3}
\end{demohigh}
\end{function}

\begin{function}{\intMathSub}
\begin{syntax}
\cs{intMathSub} \Arg{integer expression_1} \Arg{integer expression_2}
\end{syntax}
Subtracts \Arg{integer expression_2} from \Arg{integer expression_1},
and returns the result. For example
\begin{demohigh}
\intMathSub {7} {3}
\end{demohigh}
\end{function}

\begin{function}{\intMathMult}
\begin{syntax}
\cs{intMathMult} \Arg{integer expression_1} \Arg{integer expression_2}
\end{syntax}
Multiplies \Arg{integer expression_1} by \Arg{integer expression_2},
and returns the result. For example
\begin{demohigh}
\intMathMult {7} {3}
\end{demohigh}
\end{function}

\begin{function}{\intMathDiv}
\begin{syntax}
\cs{intMathDiv} \Arg{integer expression_1} \Arg{integer expression_2}
\end{syntax}
Evaluates the two \meta{integer expressions} as described earlier,
then divides the first value by the second, and rounds the result
to the closest integer. Ties are rounded away from zero. Note that
this is identical to using \verb|/| directly in an \meta{integer expression}.
The result is returned as an \meta{integer denotation}.
For example
\begin{demohigh}
\intMathDiv {8} {3}
\end{demohigh}
\end{function}

\begin{function}{\intMathDivTrancate}
\begin{syntax}
\cs{intMathDivTrancate} \Arg{integer expression_1} \Arg{integer expression_2}
\end{syntax}
Evaluates the two \meta{integer expressions} as described earlier,
then divides the first value by the second, and rounds the result towards zero.
Note that division using \verb|/| rounds to the closest integer instead.
The result is returned as an \meta{integer denotation}.
For example
\begin{demohigh}
\intMathDivTruncate {8} {3}
\end{demohigh}
\end{function}

\begin{function}{\intMathSign}
\begin{syntax}
\cs{intMathSign} \Arg{intexpr}
\end{syntax}
Evaluates the \meta{integer expression} then leaves $1$ or $0$ or
$-1$ in the input stream according to the sign of the result.
\end{function}

\begin{function}{\intMathAbs}
\begin{syntax}
\cs{intMathAbs} \Arg{integer expression}
\end{syntax}
Evaluates the \meta{integer expression} as described for
\cs{intEval} and leaves the absolute value of the result in
the input stream as an \meta{integer denotation} after two
expansions.
\end{function}

\begin{function}{\intMathMax,\intMathMin}
\begin{syntax}
\cs{intMathMax} \Arg{intexpr_1} \Arg{intexpr_2}
\cs{intMathMin} \Arg{intexpr_1} \Arg{intexpr_2}
\end{syntax}
Evaluates the \meta{integer expressions} as described for
\cs{intEval} and leaves either the larger or smaller value
in the input stream as an \meta{integer denotation} after two
expansions.
\end{function}

\begin{function}{\intMathMod}
\begin{syntax}
\cs{intMathMod} \Arg{intexpr_1} \Arg{intexpr_2}
\end{syntax}
Evaluates the two \meta{integer expressions} as described earlier,
then calculates the integer remainder of dividing the first
expression by the second.  This is obtained by subtracting
\cs{intMathDivTruncate} \Arg{intexpr_1} \Arg{intexpr_2} times
\meta{intexpr_2} from \meta{intexpr_1}.  Thus, the result has the
same sign as \meta{intexpr_1} and its absolute value is strictly
less than that of \meta{intexpr_2}.  The result is left in the input
stream as an \meta{integer denotation} after two expansions.
\end{function}

\begin{function}{\intMathRand}
\begin{syntax}
\cs{intMathRand} \Arg{intexpr_1} \Arg{intexpr_2}
\end{syntax}
Evaluates the two \meta{integer expressions} and produces a
pseudo-random number between the two (with bounds included).
%This is not available in older versions of \XeTeX{}.
\end{function}

\section{Creating and Using Integers}

\begin{function}{\intNew}
\begin{syntax}
\cs{intNew} \meta{integer}
\end{syntax}
Creates a new \meta{integer} or raises an error if the name is
already taken. The declaration is global. The \meta{integer} is
initially equal to $0$.
\end{function}

\begin{function}{\intConst}
\begin{syntax}
\cs{intConst} \meta{integer} \Arg{integer expression}
\end{syntax}
Creates a new constant \meta{integer} or raises an error if the name
is already taken. The value of the \meta{integer} is set
globally to the \meta{integer expression}.
\end{function}

\begin{function}{\intUse}
\begin{syntax}
\cs{intUse} \meta{integer}
\end{syntax}
Recovers the content of an \meta{integer} and returns the value.
An error is raised if the variable does not exist or if it is invalid.
\end{function}

\section{Viewing Integers}

\begin{function}{\intLog}
\begin{syntax}
\cs{intLog} \Arg{integer expression}
\end{syntax}
Writes the result of evaluating the \meta{integer expression}
in the log file.
\end{function}

\begin{function}{\intVarLog}
\begin{syntax}
\cs{intVarLog} \meta{integer}
\end{syntax}
Writes the value of the \meta{integer} in the log file.
\end{function}

\begin{function}{\intShow}
\begin{syntax}
\cs{intShow} \Arg{integer expression}
\end{syntax}
Displays the result of evaluating the \meta{integer expression}
on the terminal.
\end{function}

\begin{function}{\intVarShow}
\begin{syntax}
\cs{intVarShow} \meta{integer}
\end{syntax}
Displays the value of the \meta{integer} on the terminal.
\end{function}

\section{Setting Integer Variables}

\begin{function}{\intSet}
\begin{syntax}
\cs{intSet} \meta{integer} \Arg{integer expression}
\end{syntax}
Sets \meta{integer} to the value of \meta{integer expression},
which must evaluate to an integer (as described for \cs{intEval}).
For example
\begin{demohigh}
\intSet \lTmpaInt {3+5}
\intUse \lTmpaInt
\end{demohigh}
\end{function}

\begin{function}{\intSetEq}
\begin{syntax}
\cs{intSetEq} \meta{integer_1} \meta{integer_2}
\end{syntax}
Sets the content of \meta{integer_1} equal to that of
\meta{integer_2}.
\end{function}

\begin{function}{\intZero}
\begin{syntax}
\cs{intZero} \meta{integer}
\end{syntax}
Sets \meta{integer} to $0$. For example
\begin{demohigh}
\intSet \lTmpaInt {5}
\intZero \lTmpaInt
\intUse \lTmpaInt
\end{demohigh}
\end{function}

\begin{function}{\intZeroNew}
\begin{syntax}
\cs{intZeroNew} \meta{integer}
\end{syntax}
Ensures that the \meta{integer} exists globally by applying
\cs{intNew} if necessary, then applies \cs{intZero} to leave
the \meta{integer} set to zero.
\end{function}

\begin{function}{\intIncr}
\begin{syntax}
\cs{intIncr} \meta{integer}
\end{syntax}
Increases the value stored in \meta{integer} by $1$.
For example
\begin{demohigh}
\intSet \lTmpaInt {5}
\intIncr \lTmpaInt
\intUse \lTmpaInt
\end{demohigh}
\end{function}

\begin{function}{\intDecr}
\begin{syntax}
\cs{intDecr} \meta{integer}
\end{syntax}
Decreases the value stored in \meta{integer} by $1$.
For example
\begin{demohigh}
\intSet \lTmpaInt {5}
\intDecr \lTmpaInt
\intUse \lTmpaInt
\end{demohigh}
\end{function}

\begin{function}{\intAdd}
\begin{syntax}
\cs{intAdd} \meta{integer} \Arg{integer expression}
\end{syntax}
Adds the result of the \meta{integer expression} to the current
content of the \meta{integer}. For example
\begin{demohigh}
\intSet \lTmpaInt {5}
\intAdd \lTmpaInt {2}
\intUse \lTmpaInt
\end{demohigh}
\end{function}

\begin{function}{\intSub}
\begin{syntax}
\cs{intSub} \meta{integer} \Arg{integer expression}
\end{syntax}
Subtracts the result of the \meta{integer expression} from the
current content of the \meta{integer}. For example
\begin{demohigh}
\intSet \lTmpaInt {5}
\intSub \lTmpaInt {3}
\intUse \lTmpaInt
\end{demohigh}
\end{function}

\section{Integer Step Functions}

\begin{function}{\intReplicate}
\begin{syntax}
\cs{intReplicate} \Arg{integer expression} \Arg{tokens}
\end{syntax}
Evaluates the \meta{integer expression} (which should be zero or positive)
and returns the resulting number of copies of the \meta{tokens}.
\begin{demohigh}
\intReplicate {4} {Hello}
\end{demohigh}
\end{function}

%\begin{function}{\intStepFunction}
%\begin{syntax}
%\cs{intStepFunction} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
%\end{syntax}
%This function first evaluates the \meta{initial value}, \meta{step}
%and \meta{final value}, all of which should be integer expressions.
%The \meta{function} is then placed in front of each \meta{value}
%from the \meta{initial value} to the \meta{final value} in turn
%(using \meta{step} between each \meta{value}).  The \meta{step} must
%be non-zero.  If the \meta{step} is positive, the loop stops when
%the \meta{value} becomes larger than the \meta{final value}.  If the
%\meta{step} is negative, the loop stops when the \meta{value}
%becomes smaller than the \meta{final value}.  The \meta{function}
%should absorb one numerical argument. For example
%\begin{verbatim}
%\cs_set:Npn \my_func:n #1 { [I~saw~#1] \quad }
%\int_step_function:nnnN { 1 } { 1 } { 5 } \my_func:n
%\end{verbatim}
%would print
%\begin{quote}
%[I saw 1] \quad
%[I saw 2] \quad
%[I saw 3] \quad
%[I saw 4] \quad
%[I saw 5] \quad
%\end{quote}
%\end{function}

\begin{function}{\intStepInline}
\begin{syntax}
\cs{intStepInline} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value}, \meta{step}
and \meta{final value}, all of which should be integer expressions.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using \meta{step} between each
\meta{value}), the \meta{code} is inserted into the input stream
with \verb|#1| replaced by the current \meta{value}. Thus the
\meta{code} should define a function of one argument~(\verb|#1|).
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\intStepInline {1} {3} {30} {
  \tlPutRight \lTmpaTl {[#1]}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\intStepOneInline}
\begin{syntax}
\cs{intStepOneInline} \Arg{initial value} \Arg{final value} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value} and \meta{final value},
all of which should be integer expressions.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using a fixed step of $1$ between each
\meta{value}), the \meta{code} is inserted into the input stream
with \verb|#1| replaced by the current \meta{value}. Thus the
\meta{code} should define a function of one argument~(\verb|#1|).
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\intStepOneInline {1} {10} {
  \tlPutRight \lTmpaTl {[#1]}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\intStepVariable}
\begin{syntax}
\cs{intStepVariable} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl var} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value}, \meta{step}
and \meta{final value}, all of which should be integer expressions.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using \meta{step} between each
\meta{value}), the \meta{code} is evaluated,
with the \meta{tl~var} defined as the current \meta{value}. Thus
the \meta{code} should make use of the \meta{tl~var}.
%For example
%\begin{demohigh}
%\IgnoreSpacesOn
%\tlClear\lTmpaTl
%\intStepVariable{1}{3}{30}\lTmpiTl{
%  \tlPutRight\lTmpaTl{\expValue\lTmpiTl}
%  \tlPutRight\lTmpaTl{~}
%}
%\prgReturn{\expValue\lTmpaTl}
%\IgnoreSpacesOff
%\end{demohigh}
\end{function}

\begin{function}{\intStepOneVariable}
\begin{syntax}
\cs{intStepOneVariable} \Arg{initial value} \Arg{final value} \meta{tl var} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value} and \meta{final value},
all of which should be integer expressions.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using a fixed stop of $1$ between each
\meta{value}), the \meta{code} is evaluated,
with the \meta{tl~var} defined as the current \meta{value}. Thus
the \meta{code} should make use of the \meta{tl~var}.
\end{function}

\section{Integer Conditionals}

\begin{function}{\intIfExist,\intIfExistT,\intIfExistF,\intIfExistTF}
\begin{syntax}
\cs{intIfExist} \meta{integer}
\cs{intIfExistT} \meta{integer} \Arg{true code}
\cs{intIfExistF} \meta{integer} \Arg{false code}
\cs{intIfExistTF} \meta{integer} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{integer} is currently defined.  This does not
check that the \meta{integer} really is an integer variable.
\end{function}

\begin{function}{\intIfOdd,\intIfOddT,\intIfOddF,\intIfOddTF}
\begin{syntax}
\cs{intIfOdd} \Arg{integer expression}
\cs{intIfOddT} \Arg{integer expression} \Arg{true code}
\cs{intIfOddF} \Arg{integer expression} \Arg{false code}
\cs{intIfOddTF} \Arg{integer expression} \Arg{true code} \Arg{false code}
\end{syntax}
This function first evaluates the \meta{integer expression}
as described for \cs{intEval}.
It then evaluates if this is odd or even, as appropriate.
\end{function}

\begin{function}{\intIfEven,\intIfEvenT,\intIfEvenF,\intIfEvenTF}
\begin{syntax}
\cs{intIfEven} \Arg{integer expression}
\cs{intIfEvenT} \Arg{integer expression} \Arg{true code}
\cs{intIfEvenF} \Arg{integer expression} \Arg{false code}
\cs{intIfEvenTF} \Arg{integer expression} \Arg{true code} \Arg{false code}
\end{syntax}
This function first evaluates the \meta{integer expression}
as described for \cs{intEval}.
It then evaluates if this is even or odd, as appropriate.
\end{function}

\begin{function}{\intCompare,\intCompareT,\intCompareF,\intCompareTF}
\begin{syntax}
\cs{intCompare} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2}
\cs{intCompareT} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{true code}
\cs{intCompareF} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{false code}
\cs{intCompareTF} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{true code} \Arg{false code}
\end{syntax}
This function first evaluates each of the \meta{integer expressions}
as described for \cs{intEval}. The two results are then
compared using the \meta{relation}:\par
{\centering\begin{tabular}{ll}
Equal        & \texttt{=} \\
Greater than & \texttt{>} \\
Less than    & \texttt{<} \\
\end{tabular}\par}
For example
\begin{demohigh}
\intCompareTF {2} > {1} {\prgReturn{Greater}} {\prgReturn{Less}}
\intCompareTF {2} > {3} {\prgReturn{Greater}} {\prgReturn{Less}}
\end{demohigh}
\end{function}

\section{Integer Case Functions}

\begin{function}{\intCase}
\begin{syntax}
\cs{intCase} \Arg{test integer expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{intexpr case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{intexpr case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{intexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
\end{syntax}
This function evaluates the \meta{test integer expression} and
compares this in turn to each of the
\meta{integer expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded.
\end{function}

\begin{function}{\intCaseT}
\begin{syntax}
\cs{intCaseT} \Arg{test integer expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{intexpr case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{intexpr case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{intexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{true code}
\end{syntax}
This function evaluates the \meta{test integer expression} and
compares this in turn to each of the
\meta{integer expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case).
\end{function}

\begin{function}{\intCaseF}
\begin{syntax}
\cs{intCaseF} \Arg{test integer expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{intexpr case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{intexpr case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{intexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{false code}
\end{syntax}
This function evaluates the \meta{test integer expression} and
compares this in turn to each of the
\meta{integer expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded. If none
match then the \meta{false code} is into the input stream
(after the code for the appropriate case).
For example
\begin{demohigh}
\IgnoreSpacesOn
\intCaseF { 2 * 5 }
  {
    { 5 }       { Small }
    { 4 + 6 }   { Medium }
    { -2 * 10 } { Negative }
  }
  { No idea! }
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\intCaseTF}
\begin{syntax}
\cs{intCaseTF} \Arg{test integer expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{intexpr case_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{intexpr case_2} \Arg{code case_2}
~ ~ ~ ~ $\cdots$
~ ~ ~ ~ \Arg{intexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{true code}
~ ~ \Arg{false code}
\end{syntax}
This function evaluates the \meta{test integer expression} and
compares this in turn to each of the
\meta{integer expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case), while if none
match then the \meta{false code} is inserted.
\end{function}

\chapter{Floating Point Numbers (\texttt{Fp})}

\section{Constant and Scratch Floating Points}

\begin{variable}{\cZeroFp, \cMinusZeroFp}
Zero, with either sign.
\end{variable}

\begin{variable}{\cOneFp}
One as an \texttt{fp}: useful for comparisons in some places.
\end{variable}

\begin{variable}{\cInfFp,\cMinusInfFp}
Infinity, with either sign. These can be input directly in a
floating point expression as \texttt{inf} and \texttt{-inf}.
\end{variable}

\begin{variable}{\cEFp}
The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$.
\end{variable}

\begin{variable}{\cPiFp}
The value of $\pi$.  This can be input directly in a floating point
expression as \texttt{pi}.
\end{variable}

\begin{variable}{\cOneDegreeFp}
The value of $1^{\circ}$ in radians. Multiply an angle given in
degrees by this value to obtain a result in radians.  Note that
trigonometric functions expecting an argument in radians or in
degrees are both available.  Within floating point expressions, this
can be accessed as \texttt{deg}.
\end{variable}

\begin{variable}{\lTmpaFp,\lTmpbFp,\lTmpcFp,\lTmpiFp,\lTmpjFp,\lTmpkFp}
Scratch floating point numbers for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaFp,\gTmpbFp,\gTmpcFp,\gTmpiFp,\gTmpjFp,\gTmpkFp}
Scratch floating point numbers for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{The Syntax of Floating Point Expressions}

A decimal floating point number is one which is stored as a significand and a
separate exponent. The module implements expandably a wide set of
arithmetic, trigonometric, and other operations on decimal floating point
numbers, to be used within floating point expressions. Floating point
expressions support the following operations with their usual
precedence.
\begin{itemize}
\item Basic arithmetic: addition $x+y$, subtraction $x-y$,
multiplication $x*y$, division $x/y$, square root $\sqrt{x}$,
and parentheses.
\item Comparison operators: $x\mathop{\mathtt{<}}y$,
$x\mathop{\mathtt{<=}}y$, $x\mathop{\mathtt{>?}}y$,
$x\mathop{\mathtt{!=}}y$ \emph{etc.}
\item Boolean logic: sign $\operatorname{sign} x$,
negation $\mathop{!}x$, conjunction
$x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary
operator $x\mathop{?}y\mathop{:}z$.
\item Exponentials: $\exp x$, $\ln x$, $x^y$, $\operatorname{logb} x$.
\item Integer factorial: $\operatorname{fact} x$.
\item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec
x$, $\csc x$ expecting their arguments in radians, and
$\operatorname{sind} x$, $\operatorname{cosd} x$,
$\operatorname{tand} x$, $\operatorname{cotd} x$,
$\operatorname{secd} x$, $\operatorname{cscd} x$ expecting their
arguments in degrees.
\item Inverse trigonometric functions: $\operatorname{asin} x$,
$\operatorname{acos} x$, $\operatorname{atan} x$,
$\operatorname{acot} x$, $\operatorname{asec} x$,
$\operatorname{acsc} x$ giving a result in radians, and
$\operatorname{asind} x$, $\operatorname{acosd} x$,
$\operatorname{atand} x$, $\operatorname{acotd} x$,
$\operatorname{asecd} x$, $\operatorname{acscd} x$ giving a result
in degrees.
%\item [\emph{(not yet)}] Hyperbolic functions and their inverse
%functions: $\sinh x$, $\cosh x$, $\tanh x$, $\coth x$,
%$\operatorname{sech} x$, $\operatorname{csch}$, and
%$\operatorname{asinh} x$, $\operatorname{acosh} x$,
%$\operatorname{atanh} x$, $\operatorname{acoth} x$,
%$\operatorname{asech} x$, $\operatorname{acsch} x$.
\item Extrema: $\max(x_{1},x_{2},\ldots)$, $\min(x_{1},x_{2},\ldots)$,
$\operatorname{abs}(x)$.
\item Rounding functions, controlled by two optional
values,  $n$ (number of places, $0$ by default) and
$t$ (behavior on a tie, $\nan$ by default):
\begin{itemize}
\item $\operatorname{trunc}(x,n)$ rounds towards zero,
\item $\operatorname{floor}(x,n)$ rounds towards $-\infty$,
\item $\operatorname{ceil}(x,n)$ rounds towards $+\infty$,
\item $\operatorname{round}(x,n,t)$ rounds to the closest value, with
ties rounded to an even value by default, towards zero if $t=0$,
towards $+\infty$ if $t>0$ and towards $-\infty$ if $t<0$.
\end{itemize}
%And \emph{(not yet)} modulo, and \enquote{quantize}.
\item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$.
\item Constants: \texttt{pi}, \texttt{deg} (one degree in radians).
\item Dimensions, automatically expressed in points, \emph{e.g.},
\texttt{pc} is $12$.
\item Automatic conversion (no need for \cs{intUse}, etc) of
integer, dimension, and skip variables to floating point numbers,
expressing dimensions in points and ignoring the stretch and
shrink components of skips.
\item Tuples: $(x_1,\ldots{},x_n)$ that can be stored in variables,
added together, multiplied or divided by a floating point number,
and nested.
\end{itemize}
Floating point numbers can be given either explicitly (in a form such
as \verb|1.234e-34|, or \verb|-.0001|), or as a stored floating point variable,
which is automatically replaced by its current value.
A \enquote{floating point} is a floating point number or a tuple thereof.
%See section \ref{sec:l3fp:fp-floats} for a description of what a floating point is,
%section \ref{sec:l3fp:fp-precedence} for details about how an expression is
%parsed, and section \ref{sec:l3fp:fp-operations} to know what the various
%operations do.  Some operations may raise exceptions (error messages),
%described in section \ref{sec:l3fp:fp-exceptions}.

An example of use could be the following.
\begin{demohigh}
\LaTeX{} can now compute: $ \frac{\sin(3.5)}{2} + 2\cdot 10^{-3}
= \fpEval {sin(3.5)/2 + 2e-3} $.
\end{demohigh}

The operation \texttt{round} can be used to limit the result's
precision. Adding $+0$ avoids the possibly undesirable output \verb|-0|,
replacing it by \verb|+0|.

%However, the \pkg{l3fp} module is mostly meant
%as an underlying tool for higher-level commands.  For example, one
%could provide a function to typeset nicely the result of floating
%point computations.
%\begin{verbatim}
%\documentclass{article}
%\usepackage{xparse, siunitx}
%\ExplSyntaxOn
%\NewDocumentCommand { \calcnum } { m }
%{ \num { \fp_to_scientific:n {#1} } }
%\ExplSyntaxOff
%\begin{document}
%\calcnum { 2 pi * sin ( 2.3 ^ 5 ) }
%\end{document}
%\end{verbatim}
%See the documentation of \pkg{siunitx} for various options of
%\cs{num}.

\section{Using Floating Point Expressions}

\begin{function}{\fpEval}
\begin{syntax}
\cs{fpEval} \Arg{floating point expression}
\end{syntax}
Evaluates the \meta{floating point expression} and returns the
result as a decimal number with no
exponent.  Leading or trailing zeros may be inserted to compensate
for the exponent.  Non-significant trailing zeros are trimmed, and
integers are expressed without a decimal separator.  The values
$\pm\infty$ and \nan{} trigger an \enquote{invalid operation}
exception.
For a tuple, each item is converted using \cs{fpEval} and they are combined as
\verb|(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}\verb|)|
if $n>1$ and \verb|(|\meta{fp_1}\verb|,)| or \verb|()| for fewer items.
%This function is identical to \cs{fp_to_decimal:n}.
For example
\begin{demohigh}
\fpEval {(1.2+3.4)*(5.6-7.8)/9}
\end{demohigh}
\end{function}

\begin{function}{\fpMathAdd}
\begin{syntax}
\cs{fpMathAdd} \Arg{fpexpr_1} \Arg{fpexpr_2}
\end{syntax}
Adds \Arg{fpexpr_1} and \Arg{fpexpr_2},
and returns the result. For example
\begin{demohigh}
\fpMathAdd {2.8} {3.7}
\fpMathAdd {3.8-1} {2.7+1}
\end{demohigh}
\end{function}

\begin{function}{\fpMathSub}
\begin{syntax}
\cs{fpMathSub} \Arg{fpexpr_1} \Arg{fpexpr_2}
\end{syntax}
Subtracts \Arg{fpexpr_2} from \Arg{fpexpr_1},
and returns the result. For example
\begin{demohigh}
\fpMathSub {2.8} {3.7}
\fpMathSub {3.8-1} {2.7+1}
\end{demohigh}
\end{function}

\begin{function}{\fpMathMult}
\begin{syntax}
\cs{fpMathMult} \Arg{fpexpr_1} \Arg{fpexpr_2}
\end{syntax}
Multiplies \Arg{fpexpr_1} by \Arg{fpexpr_2},
and returns the result. For example
\begin{demohigh}
\fpMathMult {2.8} {3.7}
\fpMathMult {3.8-1} {2.7+1}
\end{demohigh}
\end{function}

\begin{function}{\fpMathDiv}
\begin{syntax}
\cs{fpMathDiv} \Arg{fpexpr_1} \Arg{fpexpr_2}
\end{syntax}
Divides \Arg{fpexpr_1} by \Arg{fpexpr_2},
and returns the result. For example
\begin{demohigh}
\fpMathDiv {2.8} {3.7}
\fpMathDiv {3.8-1} {2.7+1}
\end{demohigh}
\end{function}

\begin{function}{\fpMathSign}
\begin{syntax}
\cs{fpMathSign} \Arg{fpexpr}
\end{syntax}
Evaluates the \meta{fpexpr} and returns the value
using \cs{fpEval}\verb|{sign(|\meta{result}\verb|)}|: $+1$ for positive
numbers and for $+\infty$, $-1$ for negative numbers and for
$-\infty$, $\pm 0$ for $\pm 0$.  If the operand is a tuple or is
\nan{}, then \enquote{invalid operation} occurs and the result
is $0$. For example
\begin{demohigh}
\fpMathSign {3.5}
\fpMathSign {-2.7}
\end{demohigh}
\end{function}

\begin{function}{\fpMathAbs}
\begin{syntax}
\cs{fpMathAbs} \Arg{floating point expression}
\end{syntax}
Evaluates the \meta{floating point expression} as described for
\cs{fpEval} and returns the absolute value.
If the argument is $\pm\infty$, \nan{} or a tuple,
\enquote{invalid operation} occurs.  Within floating point
expressions, \verb|abs()| can be used; it accepts $\pm\infty$ and \nan{}
as arguments.
\end{function}

\begin{function}{\fpMathMax,\fpMathMin}
\begin{syntax}
\cs{fpMathMax} \Arg{fp expression_1} \Arg{fp expression_2}
\cs{fpMathMin} \Arg{fp expression_1} \Arg{fp expression_2}
\end{syntax}
Evaluates the \meta{floating point expressions} as described for \cs{fpEval}
and returns the resulting larger (\texttt{max}) or smaller (\texttt{min}) value.
If the argument is a tuple, \enquote{invalid operation} occurs,
but no other case raises exceptions. Within floating point expressions,
\verb|max()| and \verb|min()| can be used.
\end{function}

\section{Creating and Using Floating Points}

\begin{function}{\fpNew}
\begin{syntax}
\cs{fpNew} \meta{fp var}
\end{syntax}
Creates a new \meta{fp var} or raises an error if the name is
already taken. The declaration is global. The \meta{fp~var} is
initially $+0$.
\end{function}

\begin{function}{\fpConst}
\begin{syntax}
\cs{fpConst} \meta{fp var} \Arg{floating point expression}
\end{syntax}
Creates a new constant \meta{fp var} or raises an error if the name
is already taken. The \meta{fp var} is set globally equal to
the result of evaluating the \meta{floating point expression}.
For example
\begin{demohigh}
\fpConst \cMyPiFp {3.1415926}
\fpUse \cMyPiFp
\end{demohigh}
\end{function}

\begin{function}{\fpUse}
\begin{syntax}
\cs{fpUse} \meta{fp var}
\end{syntax}
Recovers the value of the \meta{fp var} and returns the value as a
decimal number with no exponent.
%Leading or trailing zeros may be inserted to compensate for the
%exponent.  Non-significant trailing zeros are trimmed.  Integers are
%expressed without a decimal separator.  The values $\pm\infty$
%and \nan{} trigger an \enquote{invalid operation} exception.
%For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
%|(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
%if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
%This function is identical to \cs{fp_to_decimal:N}.
\end{function}

\section{Viewing Floating Points}

\begin{function}{\fpLog}
\begin{syntax}
\cs{fpLog} \Arg{floating point expression}
\end{syntax}
Evaluates the \meta{floating point expression} and writes the
result in the log file.
\end{function}

\begin{function}{\fpVarLog}
\begin{syntax}
\cs{fpVarLog} \meta{fp var}
\end{syntax}
Writes the value of \meta{fp var} in the log file.
\end{function}

\begin{function}{\fpShow}
\begin{syntax}
\cs{fpShow} \Arg{floating point expression}
\end{syntax}
Evaluates the \meta{floating point expression} and displays the
result in the terminal.
\end{function}

\begin{function}{\fpVarShow}
\begin{syntax}
\cs{fpVarShow} \meta{fp var}
\end{syntax}
Displays the value of \meta{fp var} in the terminal.
\end{function}

\section{Setting Floating Point Variables}

\begin{function}{\fpSet}
\begin{syntax}
\cs{fpSet} \meta{fp var} \Arg{floating point expression}
\end{syntax}
Sets \meta{fp var} equal to the result of computing the
\meta{floating point expression}. For example
\begin{demohigh}
\fpSet \lTmpaFp {4/7}
\fpUse \lTmpaFp
\end{demohigh}
\end{function}

\begin{function}{\fpSetEq}
\begin{syntax}
\cs{fpSetEq} \meta{fp var_1} \meta{fp var_2}
\end{syntax}
Sets the floating point variable \meta{fp var_1} equal to the current
value of \meta{fp var_2}.
\end{function}

\begin{function}{\fpZero}
\begin{syntax}
\cs{fpZero} \meta{fp var}
\end{syntax}
Sets the \meta{fp var} to $+0$. For example
\begin{demohigh}
\fpSet \lTmpaFp {5.3}
\fpZero \lTmpaFp
\fpUse \lTmpaFp
\end{demohigh}
\end{function}

\begin{function}{\fpZeroNew}
\begin{syntax}
\cs{fpZeroNew} \meta{fp var}
\end{syntax}
Ensures that the \meta{fp var} exists globally
by applying \cs{fpNew} if necessary, then applies
\cs{fpZero} to leave the \meta{fp var} set to $+0$.
\end{function}

\begin{function}{\fpAdd}
\begin{syntax}
\cs{fpAdd} \meta{fp var} \Arg{floating point expression}
\end{syntax}
Adds the result of computing the \meta{floating point expression} to
the \meta{fp var}.
This also applies if \meta{fp var} and \meta{floating point
expression} evaluate to tuples of the same size. For example
\begin{demohigh}
\fpSet \lTmpaFp {5.3}
\fpAdd \lTmpaFp {2.11}
\fpUse \lTmpaFp
\end{demohigh}
\end{function}

\begin{function}{\fpSub}
\begin{syntax}
\cs{fpSub} \meta{fp var} \Arg{floating point expression}
\end{syntax}
Subtracts the result of computing the \meta{floating point
expression} from the \meta{fp var}.
This also applies if \meta{fp var} and \meta{floating point
expression} evaluate to tuples of the same size. For example
\begin{demohigh}
\fpSet \lTmpaFp {5.3}
\fpSub \lTmpaFp {2.11}
\fpUse \lTmpaFp
\end{demohigh}
\end{function}

\section{Floating Point Step Functions}

%\begin{function}{\fpStepFunction}
%\begin{syntax}
%\cs{fpStepFunction} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
%\end{syntax}
%This function first evaluates the \meta{initial value}, \meta{step}
%and \meta{final value}, each of which should be a floating point
%expression evaluating to a floating point number, not a tuple.
%The \meta{function} is then placed in front of each \meta{value}
%from the \meta{initial value} to the \meta{final value} in turn
%(using \meta{step} between each \meta{value}).  The \meta{step} must
%be non-zero.  If the \meta{step} is positive, the loop stops when
%the \meta{value} becomes larger than the \meta{final value}.  If the
%\meta{step} is negative, the loop stops when the \meta{value}
%becomes smaller than the \meta{final value}. The \meta{function}
%should absorb one numerical argument. For example
%\begin{verbatim}
%\cs_set:Npn \my_func:n #1 { [I saw #1] \quad }
%\fp_step_function:nnnN { 1.0 } { 0.1 } { 1.5 } \my_func:n
%\end{verbatim}
%would print
%\begin{quote}
%[I saw 1.0] \quad
%[I saw 1.1] \quad
%[I saw 1.2] \quad
%[I saw 1.3] \quad
%[I saw 1.4] \quad
%[I saw 1.5] \quad
%\end{quote}
%\begin{texnote}
%Due to rounding, it may happen that adding the \meta{step} to the
%\meta{value} does not change the \meta{value}; such cases give an
%error, as they would otherwise lead to an infinite loop.
%\end{texnote}
%\end{function}

\begin{function}{\fpStepInline}
\begin{syntax}
\cs{fpStepInline} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value}, \meta{step}
and \meta{final value}, all of which should be floating point
expressions evaluating to a floating point number, not a tuple.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using \meta{step} between each
\meta{value}), the \meta{code} is inserted into the input stream
with \verb|#1| replaced by the current \meta{value}. Thus the
\meta{code} should define a function of one argument (\verb|#1|).
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\fpStepInline {1} {0.1} {1.5} {
  \tlPutRight \lTmpaTl {[#1]}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\fpStepVariable}
\begin{syntax}
\cs{fpStepVariable} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl var} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value}, \meta{step}
and \meta{final value}, all of which should be floating point
expressions evaluating to a floating point number, not a tuple.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using \meta{step} between each
\meta{value}), the \meta{code} is inserted into the input stream,
with the \meta{tl var} defined as the current \meta{value}.  Thus
the \meta{code} should make use of the \meta{tl var}.
%For example
%\begin{demohigh}
%\IgnoreSpacesOn
%\tlClear\lTmpaTl
%\fpStepVariable{1}{0.1}{1.5}\lTmpiTl{
%  \tlPutRight\lTmpaTl{\expValue\lTmpiTl}
%  \tlPutRight\lTmpaTl{~}
%}
%\prgReturn{\expValue\lTmpaTl}
%\IgnoreSpacesOff
%\end{demohigh}
\end{function}

\section{Float Point Conditionals}

\begin{function}{\fpIfExist,\fpIfExistT,\fpIfExistF,\fpIfExistTF}
\begin{syntax}
\cs{fpIfExist} \meta{fp var}
\cs{fpIfExistT} \meta{fp var} \Arg{true code}
\cs{fpIfExistF} \meta{fp var} \Arg{false code}
\cs{fpIfExistTF} \meta{fp var} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{fp var} is currently defined.  This does not
check that the \meta{fp var} really is a floating point variable.
For example
\begin{demohigh}
\fpIfExistTF \lTmpaFp {\prgReturn{Yes}} {\prgReturn{No}}
\fpIfExistTF \lMyUndefinedFp {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\fpCompare,\fpCompareT,\fpCompareF,\fpCompareTF}
\begin{syntax}
\cs{fpCompare} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2}
\cs{fpCompareT} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{true code}
\cs{fpCompareF} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{false code}
\cs{fpCompareTF} \Arg{fpexpr_1} \meta{relation} \Arg{fpexpr_2} \Arg{true code} \Arg{false code}
\end{syntax}
Compares the \meta{fpexpr_1} and the \meta{fpexpr_2}, and returns
\texttt{true} if the \meta{relation} is obeyed. For example
\begin{demohigh}
\fpCompareTF {1} > {0.9999} {\prgReturn{Greater}} {\prgReturn{Less}}
\fpCompareTF {1} > {1.0001} {\prgReturn{Greater}} {\prgReturn{Less}}
\end{demohigh}
Two floating points
$x$ and $y$ may obey four mutually exclusive relations:
$x<y$, $x=y$, $x>y$, or $x?y$ (\enquote{not ordered}).  The last
case occurs exactly if one or both operands is \nan{} or is a tuple,
unless they are equal tuples.  Note that a \nan{} is distinct from
any value, even another \nan{}, hence $x=x$ is not true for
a \nan{}.  To test if a value is \nan{}, compare it to an arbitrary
number with the \enquote{not ordered} relation.\par
%\begin{demohigh}
%\fpCompareTF{0/0}?{0}{\prgReturn{Is~a~Nan}}{\prgReturn{Isn't~a~NaN}}
%\end{demohigh}
Tuples are equal if they have the same number of items and items
compare equal (in particular there must be no \nan{}).
At present any other comparison with tuples yields \verb|?| (not ordered).
This is experimental.
\end{function}

\chapter{Dimensions (\texttt{Dim})}

\section{Constant and Scratch Dimensions}

\begin{variable}{\cMaxDim}
The maximum value that can be stored as a dimension.  This can also
be used as a component of a skip.
\end{variable}

\begin{variable}{\cZeroDim}
A zero length as a dimension.  This can also be used as a component
of a skip.
\end{variable}

\begin{variable}{\lTmpaDim,\lTmpbDim,\lTmpcDim,\lTmpiDim,\lTmpjDim,\lTmpkDim}
Scratch dimensions for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaDim,\gTmpbDim,\gTmpcDim,\gTmpiDim,\gTmpjDim,\gTmpkDim}
Scratch dimensions for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Dimension Expressions}

\begin{function}{\dimEval}
\begin{syntax}
\cs{dimEval} \Arg{dimension expression}
\end{syntax}
Evaluates the \meta{dimension expression}, expanding any
dimensions and token list variables within the \meta{expression}
to their content (without requiring \cs{dimUse}/\cs{tlUse})
and applying the standard mathematical rules. The result of the
calculation is returned as a \meta{dimension denotation}.
%This is expressed in points (\texttt{pt}), and requires suitable
%termination if used in a \TeX{}-style assignment as it is \emph{not}
%an \meta{internal dimension}.
For example
\begin{demohigh}
\dimEval {(1.2pt+3.4pt)/9}
\end{demohigh}
%\dimEval{(1.2pt+3.4pt)*(5.6-7.8)/9}
\end{function}

\begin{function}{\dimMathAdd}
\begin{syntax}
\cs{dimMathAdd} \Arg{dimexpr_1} \Arg{dimexpr_2}
\end{syntax}
Adds \Arg{dimexpr_1} and \Arg{dimexpr_2},
and returns the result. For example
\begin{demohigh}
\dimMathAdd {2.8pt} {3.7pt}
\dimMathAdd {3.8pt-1pt} {2.7pt+1pt}
\end{demohigh}
\end{function}

\begin{function}{\dimMathSub}
\begin{syntax}
\cs{dimMathSub} \Arg{dimexpr_1} \Arg{dimexpr_2}
\end{syntax}
Subtracts \Arg{dimexpr_2} from \Arg{dimexpr_1},
and returns the result. For example
\begin{demohigh}
\dimMathSub {2.8pt} {3.7pt}
\dimMathSub {3.8pt-1pt} {2.7pt+1pt}
\end{demohigh}
\end{function}

\begin{function}{\dimMathRatio}
\begin{syntax}
\cs{dimMathRatio} \Arg{dimexpr_1} \Arg{dimexpr_2}
\end{syntax}
Parses the two \meta{dimension expressions},
then calculates the ratio of the two and returns it.
The result is a ratio expression
between two integers, with all distances converted to scaled points.
For example
\begin{demohigh}
\dimMathRatio {5pt} {10pt}
\end{demohigh}
The returned value is suitable for use inside a \meta{dimension expression}
such as
\begin{codehigh}
\dimSet \lTmpaDim {10pt*\dimMathRatio{5pt}{10pt}}
\end{codehigh}
\end{function}

\begin{function}{\dimMathSign}
\begin{syntax}
\cs{dimMathSign} \Arg{dimexpr}
\end{syntax}
Evaluates the \meta{dimexpr} then returns $1$ or $0$ or $-1$
according to the sign of the result. For example
\begin{demohigh}
\dimMathSign {3.5pt}
\dimMathSign {-2.7pt}
\end{demohigh}
\end{function}

\begin{function}{\dimMathAbs}
\begin{syntax}
\cs{dimMathAbs} \Arg{dimexpr}
\end{syntax}
Converts the \meta{dimexpr} to its absolute value,
returning the result as a \meta{dimension denotation}.
For example
\begin{demohigh}
\dimMathAbs {3.5pt}
\dimMathAbs {-2.7pt}
\end{demohigh}
\end{function}

\begin{function}{\dimMathMax,\dimMathMin}
\begin{syntax}
\cs{dimMathMax} \Arg{dimexpr_1} \Arg{dimexpr_2}
\cs{dimMathMin} \Arg{dimexpr_1} \Arg{dimexpr_2}
\end{syntax}
Evaluates the two \meta{dimension expressions} and returns either the
maximum or minimum value as appropriate as a \meta{dimension denotation}.
For example
\begin{demohigh}
\dimMathMax {3.5pt} {-2.7pt}
\dimMathMin {3.5pt} {-2.7pt}
\end{demohigh}
\end{function}

\section{Creating and Using Dimensions}

\begin{function}{\dimNew}
\begin{syntax}
\cs{dimNew} \meta{dimension}
\end{syntax}
Creates a new \meta{dimension} or raises an error if the name is
already taken. The declaration is global. The \meta{dimension}
is initially equal to $0$\,pt.
\end{function}

\begin{function}{\dimConst}
\begin{syntax}
\cs{dimConst} \meta{dimension} \Arg{dimension expression}
\end{syntax}
Creates a new constant \meta{dimension} or raises an error if the
name is already taken. The value of the \meta{dimension} is set
globally to the \meta{dimension expression}. For example
\begin{demohigh}
\dimConst \cFooSomeDim {1cm}
\dimUse \cFooSomeDim
\end{demohigh}
\end{function}

\begin{function}{\dimUse}
\begin{syntax}
\cs{dimUse} \meta{dimension}
\end{syntax}
Recovers the content of a \meta{dimension} and returns the value.
An error is raised if the variable does not exist or if it is invalid.
\end{function}

\section{Viewing Dimensions}

\begin{function}{\dimLog}
\begin{syntax}
\cs{dimLog} \Arg{dimension expression}
\end{syntax}
Writes the result of evaluating the \meta{dimension expression}
in the log file. For example
\begin{codehigh}
\dimLog {\lFooSomeDim+1cm}
\end{codehigh}
\end{function}

\begin{function}{\dimVarLog}
\begin{syntax}
\cs{dimVarLog} \meta{dimension}
\end{syntax}
Writes the value of the \meta{dimension} in the log file. For example
\begin{codehigh}
\dimVarLog \lFooSomeDim
\end{codehigh}
\end{function}

\begin{function}{\dimShow}
\begin{syntax}
\cs{dimShow} \Arg{dimension expression}
\end{syntax}
Displays the result of evaluating the \meta{dimension expression}
on the terminal. For example
\begin{codehigh}
\dimShow {\lFooSomeDim+1cm}
\end{codehigh}
\end{function}

\begin{function}{\dimVarShow}
\begin{syntax}
\cs{dimVarShow} \meta{dimension}
\end{syntax}
Displays the value of the \meta{dimension} on the terminal. For example
\begin{codehigh}
\dimVarShow \lFooSomeDim
\end{codehigh}
\end{function}

\section{Setting Dimension Variables}

\begin{function}{\dimSet}
\begin{syntax}
\cs{dimSet} \meta{dimension} \Arg{dimension expression}
\end{syntax}
Sets \meta{dimension} to the value of \meta{dimension expression}, which
must evaluate to a length with units.
\end{function}

\begin{function}{\dimSetEq}
\begin{syntax}
\cs{dimSetEq} \meta{dimension_1} \meta{dimension_2}
\end{syntax}
Sets the content of \meta{dimension_1} equal to that of
\meta{dimension_2}. For example
\begin{demohigh}
\dimSet \lTmpaDim {10pt}
\dimSetEq \lTmpbDim \lTmpaDim
\dimUse \lTmpbDim
\end{demohigh}
\end{function}

\begin{function}{\dimZero}
\begin{syntax}
\cs{dimZero} \meta{dimension}
\end{syntax}
Sets \meta{dimension} to $0$\,pt. For example
\begin{demohigh}
\dimSet \lTmpaDim {1em}
\dimZero \lTmpaDim
\dimUse \lTmpaDim
\end{demohigh}
\end{function}

\begin{function}{\dimZeroNew}
\begin{syntax}
\cs{dimZeroNew} \meta{dimension}
\end{syntax}
Ensures that the \meta{dimension} exists globally by applying
\cs{dimNew} if necessary, then applies
\cs{dimZero} to set the \meta{dimension} to zero. For example
\begin{demohigh}
\dimZeroNew \lFooSomeDim
\dimUse \lFooSomeDim
\end{demohigh}
\end{function}

\begin{function}{\dimAdd}
\begin{syntax}
\cs{dimAdd} \meta{dimension} \Arg{dimension expression}
\end{syntax}
Adds the result of the \meta{dimension expression} to the current
content of the \meta{dimension}. For example
\begin{demohigh}
\dimSet \lTmpaDim {5.3pt}
\dimAdd \lTmpaDim {2.11pt}
\dimUse \lTmpaDim
\end{demohigh}
\end{function}

\begin{function}{\dimSub}
\begin{syntax}
\cs{dimSub} \meta{dimension} \Arg{dimension expression}
\end{syntax}
Subtracts the result of the \meta{dimension expression} from the
current content of the \meta{dimension}. For example
\begin{demohigh}
\dimSet \lTmpaDim {5.3pt}
\dimSub \lTmpaDim {2.11pt}
\dimUse \lTmpaDim
\end{demohigh}
\end{function}

\section{Dimension Step Functions}

%\begin{function}{\dimStepFunction}
%\begin{syntax}
%\cs{dimStepFunction} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function}
%\end{syntax}
%This function first evaluates the \meta{initial value}, \meta{step}
%and \meta{final value}, all of which should be dimension expressions.
%The \meta{function} is then placed in front of each \meta{value}
%from the \meta{initial value} to the \meta{final value} in turn
%(using \meta{step} between each \meta{value}).  The \meta{step} must
%be non-zero.  If the \meta{step} is positive, the loop stops when
%the \meta{value} becomes larger than the \meta{final value}.  If the
%\meta{step} is negative, the loop stops when the \meta{value}
%becomes smaller than the \meta{final value}.  The \meta{function}
%should absorb one argument.
%\end{function}

\begin{function}{\dimStepInline}
\begin{syntax}
\cs{dimStepInline} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value}, \meta{step}
and \meta{final value}, all of which should be dimension expressions.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using \meta{step} between each
\meta{value}), the \meta{code} is inserted into the input stream
with \verb|#1| replaced by the current \meta{value}.  Thus the
\meta{code} should define a function of one argument (\verb|#1|).
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\dimStepInline {1pt} {0.1pt} {1.5pt} {
  \tlPutRight \lTmpaTl {[#1]}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\dimStepVariable}
\begin{syntax}
\cs{dimStepVariable} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl var} \Arg{code}
\end{syntax}
This function first evaluates the \meta{initial value}, \meta{step}
and \meta{final value}, all of which should be dimension expressions.
Then for each \meta{value} from the \meta{initial value} to the
\meta{final value} in turn (using \meta{step} between each
\meta{value}), the \meta{code} is inserted into the input stream,
with the \meta{tl var} defined as the current \meta{value}.  Thus
the \meta{code} should make use of the \meta{tl var}.
%For example
%\begin{demohigh}
%\IgnoreSpacesOn
%\tlClear\lTmpaTl
%\dimStepVariable{1pt}{0.1pt}{1.5pt}\lTmpiTl{
%  \tlPutRight\lTmpaTl{\expValue\lTmpiTl}
%  \tlPutRight\lTmpaTl{~}
%}
%\prgReturn{\expValue\lTmpaTl}
%\IgnoreSpacesOff
%\end{demohigh}
\end{function}

\section{Dimension Conditionals}

\begin{function}{\dimIfExist,\dimIfExistT,\dimIfExistF,\dimIfExistTF}
\begin{syntax}
\cs{dimIfExist} \meta{dimension}
\cs{dimIfExistT} \meta{dimension} \Arg{true code}
\cs{dimIfExistF} \meta{dimension} \Arg{false code}
\cs{dimIfExistTF} \meta{dimension} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{dimension} is currently defined.  This does
not check that the \meta{dimension} really is a dimension variable.
For example
\begin{demohigh}
\dimIfExistTF \lTmpaDim {\prgReturn{Yes}} {\prgReturn{No}}
\dimIfExistTF \lFooUndefinedDim {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\dimCompare,\dimCompareT,\dimCompareF,\dimCompareTF}
\begin{syntax}
\cs{dimCompare} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2}
\cs{dimCompareT} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{true code}
\cs{dimCompareF} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{false code}
\cs{dimCompareTF} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{true code} \Arg{false code}
\end{syntax}
This function first evaluates each of the \meta{dimension expressions}
as described for \cs{dimEval}. The two results are then
compared using the \meta{relation}:\par
{\centering
\begin{tabular}{ll}
Equal        & \verb|=| \\
Greater than & \verb|>| \\
Less than    & \verb|<| \\
\end{tabular}\par}
For example
\begin{demohigh}
\dimCompareTF {1pt} > {0.9999pt} {\prgReturn{Greater}} {\prgReturn{Less}}
\dimCompareTF {1pt} > {1.0001pt} {\prgReturn{Greater}} {\prgReturn{Less}}
\end{demohigh}
\end{function}

\section{Dimension Case Functions}

\begin{function}{\dimCase}
\begin{syntax}
\cs{dimCase} \Arg{test dimension expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{dimexpr case_1} \Arg{code case_1}
~ ~ ~ ~  \Arg{dimexpr case_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{dimexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
\end{syntax}
This function evaluates the \meta{test dimension expression} and
compares this in turn to each of the
\meta{dimension expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded.
\end{function}

\begin{function}{\dimCaseT}
\begin{syntax}
\cs{dimCaseT} \Arg{test dimension expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{dimexpr case_1} \Arg{code case_1}
~ ~ ~ ~  \Arg{dimexpr case_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{dimexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{true code}
\end{syntax}
This function evaluates the \meta{test dimension expression} and
compares this in turn to each of the
\meta{dimension expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case).
\end{function}

\begin{function}{\dimCaseF}
\begin{syntax}
\cs{dimCaseF} \Arg{test dimension expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{dimexpr case_1} \Arg{code case_1}
~ ~ ~ ~  \Arg{dimexpr case_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{dimexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{false code}
\end{syntax}
This function evaluates the \meta{test dimension expression} and
compares this in turn to each of the
\meta{dimension expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded. If none of the cases
match then the \meta{false code} is inserted.
For example
\begin{demohigh}
\IgnoreSpacesOn
\dimSet \lTmpaDim {5pt}
\dimCaseF {2\lTmpaDim} {
  {5pt}     {\prgReturn{Small}}
  {4pt+6pt} {\prgReturn{Medium}}
  {-10pt}   {\prgReturn{Negative}}
}{
  \prgReturn {No Match}
}
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\dimCaseTF}
\begin{syntax}
\cs{dimCaseTF} \Arg{test dimension expression}
~ ~ \verb|{|
~ ~ ~ ~ \Arg{dimexpr case_1} \Arg{code case_1}
~ ~ ~ ~  \Arg{dimexpr case_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{dimexpr case_n} \Arg{code case_n}
~ ~ \verb|}|
~ ~ \Arg{true code}
~ ~ \Arg{false code}
\end{syntax}
This function evaluates the \meta{test dimension expression} and
compares this in turn to each of the
\meta{dimension expression cases}. If the two are equal then the
associated \meta{code} is left in the input stream
and other cases are discarded. If any of the
cases are matched, the \meta{true code} is also inserted into the
input stream (after the code for the appropriate case), while if none
match then the \meta{false code} is inserted.
%For example
%\begin{demohigh}
%\IgnoreSpacesOn
%\dimSet\lTmpaDim{5pt}
%\dimCaseTF{2\lTmpaDim}{
%  {5pt}     {\prgReturn{Small}}
%  {4pt+6pt} {\prgReturn{Medium}}
%  {-10pt}   {\prgReturn{Negative}}
%}{
%  \prgReturn{[Some Match]}
%}{
%  \prgReturn{[No Match]}
%}
%\IgnoreSpacesOff
%\end{demohigh}
\end{function}

\chapter{Comma Separated Lists (\texttt{Clist})}

\section{Constant and Scratch Comma Lists}

\begin{variable}{\cEmptyClist}
Constant that is always empty.
\end{variable}

\begin{variable}{\lTmpaClist,\lTmpbClist,\lTmpcClist,\lTmpiClist,\lTmpjClist,\lTmpkClist}
Scratch comma lists for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaClist,\gTmpbClist,\gTmpcClist,\gTmpiClist,\gTmpjClist,\gTmpkClist}
Scratch comma lists for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Creating and Using Comma Lists}

\begin{function}{\clistNew}
\begin{syntax}
\cs{clistNew} \meta{comma list}
\end{syntax}
Creates a new \meta{comma list} or raises an error if the name is
already taken. The declaration is global. The \meta{comma list}
initially contains no items.
\begin{codehigh}
\clistNew \lFooSomeClist
\end{codehigh}
\end{function}

\begin{function}{\clistConst}
\begin{syntax}
\cs{clistConst} \meta{clist var} \Arg{comma list}
\end{syntax}
Creates a new constant \meta{clist var} or raises an error
if the name is already taken. The value of the
\meta{clist var} is set globally to the
\meta{comma list}.
\begin{codehigh}
\clistConst \cFooSomeClist {one,two,three}
\end{codehigh}
\end{function}

\begin{function}{\clistVarJoin}
\begin{syntax}
\cs{clistVarJoin} \meta{clist var} \Arg{separator}
\end{syntax}
Returns the contents of the \meta{clist var},
with the \meta{separator} between the items.
%If the comma list has a single item, it is placed in the input stream,
%and a comma list with no items produces no output.
%An error is raised if the variable does not exist or if it is invalid.
\begin{demohigh}
\clistSet \lTmpaClist { a , b , , c , {de} , f }
\clistVarJoin \lTmpaClist { and }
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{items}
%do not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\clistVarJoinExtended}
\begin{syntax}
\cs{clistVarJoinExtended} \meta{clist var} \Arg{separator between two} \Arg{separator between more than two} \Arg{separator between final two}
\end{syntax}
Returns the contents of the \meta{clist var},
with the appropriate \meta{separator} between the items. Namely, if
the comma list has more than two items, the \meta{separator between
more than two} is placed between each pair of items except the
last, for which the \meta{separator between final two} is used.  If
the comma list has exactly two items, then they are joined with
the \meta{separator between two} and returns.
%If the comma list has a single item, it is placed in the input stream,
%and a comma list with no items produces no output.
%An error is raised if the variable does not exist or if it is invalid.
\begin{demohigh}
\clistSet \lTmpaClist { a , b }
\clistVarJoinExtended \lTmpaClist { and } {, } {, and }
\end{demohigh}
\begin{demohigh}
\clistSet \lTmpaClist { a , b , , c , {de} , f }
\clistVarJoinExtended \lTmpaClist { and } {, } {, and }
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{items}
%do not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\clistJoin,\clistJoinExtended}
\begin{syntax}
\cs{clistJoin} \meta{comma list} \Arg{separator}
\cs{clistJoinExtended} \meta{comma list} \Arg{separator between two} \Arg{separator between more than two} \Arg{separator between final two}
\end{syntax}
Returns the contents of the \meta{comma list},
with the appropriate \meta{separator} between the items. As for
\cs{clistSet}, blank items are omitted, spaces are removed from
both sides of each item, then a set of braces is removed if the
resulting space-trimmed item is braced.  The \meta{separators} are
then inserted in the same way as for \cs{clistVarJoin} and
\cs{clistVarJoinExtended}, respectively.
\begin{demohigh}
\clistJoinExtended { a , b } { and } {, } {, and }
\end{demohigh}
\begin{demohigh}
\clistJoinExtended { a , b , , c , {de} , f } { and } {, } {, and }
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{items}
%do not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\section{Viewing Comma Lists}

\begin{function}{\clistLog}
\begin{syntax}
\cs{clistLog} \Arg{tokens}
\end{syntax}
Writes the entries in the comma list in the log file. See also
\cs{clistShow} which displays the result in the terminal.
\begin{codehigh}
\clistLog {one,two,three}
\end{codehigh}
\end{function}

\begin{function}{\clistVarLog}
\begin{syntax}
\cs{clistVarLog} \meta{comma list}
\end{syntax}
Writes the entries in the \meta{comma list} in the log file. See
also \cs{clistVarShow} which displays the result in the terminal.
\begin{codehigh}
\clistSet \lTmpaClist {one,two,three}
\clistVarLog \lTmpaClist
\end{codehigh}
\end{function}

\begin{function}{\clistShow}
\begin{syntax}
\cs{clistShow} \Arg{tokens}
\end{syntax}
Displays the entries in the comma list in the terminal.
\begin{codehigh}
\clistShow {one,two,three}
\end{codehigh}
\end{function}

\begin{function}{\clistVarShow}
\begin{syntax}
\cs{clistVarShow} \meta{comma list}
\end{syntax}
Displays the entries in the \meta{comma list} in the terminal.
\begin{codehigh}
\clistSet \lTmpaClist {one,two,three}
\clistVarShow \lTmpaClist
\end{codehigh}
\end{function}

\section{Setting Comma Lists}

\begin{function}{\clistSet}
\begin{syntax}
\cs{clistSet} \meta{comma list} \verb|{|\meta{item_1},\ldots{},\meta{item_n}\verb|}|
\end{syntax}
Sets \meta{comma list} to contain the \meta{items},
removing any previous content from the variable.
Blank items are omitted, spaces are removed from both sides of each
item, then a set of braces is removed if the resulting space-trimmed
item is braced.
To store some \meta{tokens} as a single \meta{item} even if the
\meta{tokens} contain commas or spaces, add a set of braces:
\cs{clistSet} \meta{comma list} \verb|{| \Arg{tokens} \verb|}|.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,three}
\clistVarJoin \lTmpaClist { and }
\end{demohigh}
\end{function}

\begin{function}{\clistSetEq}
\begin{syntax}
\cs{clistSetEq} \meta{comma list_1} \meta{comma list_2}
\end{syntax}
Sets the content of \meta{comma list_1} equal to that of
\meta{comma list_2}.  To set a token list variable equal to a comma
list variable, use \cs{tlSetEq}.  Conversely, setting a comma
list variable to a token list is unadvisable unless one checks
space-trimming and related issues.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,three,four}
\clistSetEq \lTmpbClist \lTmpaClist
\clistVarJoin \lTmpbClist { and }
\end{demohigh}
\end{function}

\begin{function}{\clistSetFromSeq}
\begin{syntax}
\cs{clistSetFromSeq} \meta{comma list} \meta{sequence}
\end{syntax}
Converts the data in the \meta{sequence} into a \meta{comma list}:
the original \meta{sequence} is unchanged.
Items which contain either spaces or commas are surrounded by braces.
\begin{demohigh}
\seqPutRight \lTmpaSeq {one}
\seqPutRight \lTmpaSeq {two}
\clistSetFromSeq \lTmpaClist \lTmpaSeq
\clistVarJoin \lTmpaClist { and }
\end{demohigh}
\end{function}

\begin{function}{\clistClear}
\begin{syntax}
\cs{clistClear} \meta{comma list}
\end{syntax}
Clears all items from the \meta{comma list}.
\begin{codehigh}
\clistSet \lTmpaClist {one,two,three,four}
\clistClear \lTmpaClist
\end{codehigh}
\end{function}

\begin{function}{\clistClearNew}
\begin{syntax}
\cs{clistClearNew} \meta{comma list}
\end{syntax}
Ensures that the \meta{comma list} exists globally by applying
\cs{clistNew} if necessary, then applies \cs{clistClear} to leave
the list empty.
\begin{demohigh}
\clistClearNew \lFooSomeClist
\clistSet \lFooSomeClist {one,two,three}
\clistVarJoin \lFooSomeClist { and }
\end{demohigh}
\end{function}

\begin{function}{\clistConcat}
\begin{syntax}
\cs{clistConcat} \meta{comma list_1} \meta{comma list_2} \meta{comma list_3}
\end{syntax}
Concatenates the content of \meta{comma list_2} and \meta{comma list_3}
together and saves the result in \meta{comma list_1}. The items in
\meta{comma list_2} are placed at the left side of the new comma list.
\begin{demohigh}
\clistSet \lTmpbClist {one,two}
\clistSet \lTmpcClist {three,four}
\clistConcat \lTmpaClist \lTmpbClist \lTmpcClist
\clistVarJoin \lTmpaClist { + }
\end{demohigh}
\end{function}

\begin{function}{\clistPutLeft}
\begin{syntax}
\cs{clistPutLeft} \meta{comma list} \verb|{|\meta{item_1},\ldots{},\meta{item_n}\verb|}|
\end{syntax}
Appends the \meta{items} to the left of the \meta{comma list}.
Blank items are omitted, spaces are removed from both sides of each
item, then a set of braces is removed if the resulting space-trimmed
item is braced.
To append some \meta{tokens} as a single \meta{item} even if the
\meta{tokens} contain commas or spaces, add a set of braces:
\cs{clistPutLeft} \meta{comma list} \verb|{| \Arg{tokens} \verb|}|.
\begin{demohigh}
\clistSet \lTmpaClist {one,two}
\clistPutLeft \lTmpaClist {zero}
\clistVarJoin \lTmpaClist { and }
\end{demohigh}
\end{function}

\begin{function}{\clistPutRight}
\begin{syntax}
\cs{clistPutRight} \meta{comma list} \verb|{|\meta{item_1},\ldots{},\meta{item_n}\verb|}|
\end{syntax}
Appends the \meta{items} to the right of the \meta{comma list}.
Blank items are omitted, spaces are removed from both sides of each
item, then a set of braces is removed if the resulting space-trimmed
item is braced.
To append some \meta{tokens} as a single \meta{item} even if the
\meta{tokens} contain commas or spaces, add a set of braces:
\cs{clistPutRight} \meta{comma list} \verb|{| \Arg{tokens} \verb|}|.
\begin{demohigh}
\clistSet \lTmpaClist {one,two}
\clistPutRight \lTmpaClist {three}
\clistVarJoin \lTmpaClist { and }
\end{demohigh}
\end{function}

\section{Modifying Comma Lists}

While comma lists are normally used as ordered lists, it may be
necessary to modify the content. The functions here may be used
to update comma lists, while retaining the order of the unaffected
entries.

\begin{function}{\clistVarRemoveDuplicates}
\begin{syntax}
\cs{clistVarRemoveDuplicates} \meta{comma list}
\end{syntax}
Removes duplicate items from the \meta{comma list}, leaving the
left most copy of each item in the \meta{comma list}.  The \meta{item}
comparison takes place on a token basis, as for \cs{tlIfEqTF}.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,one,two,three}
\clistVarRemoveDuplicates \lTmpaClist
\clistVarJoin \lTmpaClist {,}
\end{demohigh}
%\begin{texnote}
%This function iterates through every item in the \meta{comma list} and
%does a comparison with the \meta{items} already checked. It is therefore
%relatively slow with large comma lists.
%Furthermore, it may fail if any of the items in the
%\meta{comma list} contains \verb|{|, \verb|}|, or \verb|#|
%(assuming the usual \TeX{} category codes apply).
%\end{texnote}
\end{function}

\begin{function}{\clistVarRemoveAll}
\begin{syntax}
\cs{clistVarRemoveAll} \meta{comma list} \Arg{item}
\end{syntax}
Removes every occurrence of \meta{item} from the \meta{comma list}.
The \meta{item} comparison takes place on a token basis, as for
\cs{tlIfEqTF}.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,one,two,three}
\clistVarRemoveAll \lTmpaClist {two}
\clistVarJoin \lTmpaClist {,}
\end{demohigh}
%\begin{texnote}
%The function may fail if the \meta{item} contains \verb|{|, \verb|}|, or \verb|#|
%(assuming the usual \TeX{} category codes apply).
%\end{texnote}
\end{function}

\begin{function}{\clistVarReverse}
\begin{syntax}
\cs{clistVarReverse} \meta{comma list}
\end{syntax}
Reverses the order of items stored in the \meta{comma list}.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,one,two,three}
\clistVarReverse \lTmpaClist
\clistVarJoin \lTmpaClist {,}
\end{demohigh}
\end{function}

%\begin{function}{\clistVarSort}
%\begin{syntax}
%\cs{clistVarSort} \meta{clist var} \Arg{comparison code}
%\end{syntax}
%Sorts the items in the \meta{clist var} according to the
%\meta{comparison code}, and assigns the result to
%\meta{clist var}. The details of sorting comparison are
%described in Section \ref{sec:l3sort:mech}.
%\end{function}

\section{Working with the Contents of Comma Lists}

\begin{function}{\clistCount,\clistVarCount}
\begin{syntax}
\cs{clistCount} \Arg{comma list}
\cs{clistVarCount} \meta{comma list}
\end{syntax}
Returns the number of items in the \meta{comma list}
as an \meta{integer denotation}. The total number of items
in a \meta{comma list} includes those which are duplicates,
\emph{i.e.} every item in a \meta{comma list} is counted.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,three,four}
\clistVarCount \lTmpaClist
\end{demohigh}
\end{function}

\begin{function}{\clistItem}
\begin{syntax}
\cs{clistItem} \Arg{comma list} \Arg{integer expression}
\end{syntax}
Indexing items in the \meta{comma list} from $1$ at the top (left), this
function evaluates the \meta{integer expression} and returns the
appropriate item from the comma list. If the
\meta{integer expression} is negative, indexing occurs from the
bottom (right) of the comma list. When the \meta{integer expression}
is larger than the number of items in the \meta{comma list} (as
calculated by \cs{clistCount}) then the function returns nothing.
\begin{demohigh}
\tlSet \lTmpaTl {\clistItem {one,two,three,four} {3}}
\tlUse \lTmpaTl
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\clistVarItem}
\begin{syntax}
\cs{clistVarItem} \meta{comma list} \Arg{integer expression}
\end{syntax}
Indexing items in the \meta{comma list} from $1$ at the top (left), this
function evaluates the \meta{integer expression} and returns the
appropriate item from the comma list. If the
\meta{integer expression} is negative, indexing occurs from the
bottom (right) of the comma list. When the \meta{integer expression}
is larger than the number of items in the \meta{comma list} (as
calculated by \cs{clistVarCount}) then the function returns nothing.
\begin{demohigh}
\clistSet \lTmpaClist {one,two,three,four}
\tlSet \lTmpaTl {\clistVarItem \lTmpaClist {3}}
\tlUse \lTmpaTl
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\clistRandItem,\clistVarRandItem}
\begin{syntax}
\cs{clistRandItem} \Arg{comma list}
\cs{clistVarRandItem} \meta{clist var}
\end{syntax}
Selects a pseudo-random item of the \meta{comma list}.
If the \meta{comma list} has no item, the result is empty.
\begin{demohigh}
\tlSet \lTmpaTl {\clistRandItem {one,two,three,four,five,six}}
\tlUse \lTmpaTl
\tlSet \lTmpaTl {\clistRandItem {one,two,three,four,five,six}}
\tlUse \lTmpaTl
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\section{Comma Lists as Stacks}

Comma lists can be used as stacks, where data is pushed to and popped
from the top of the comma list. (The left of a comma list is the top, for
performance reasons.) The stack functions for comma lists are not
intended to be mixed with the general ordered data functions detailed
in the previous section: a comma list should either be used as an
ordered data type or as a stack, but not in both ways.

\begin{function}{\clistGet}
\begin{syntax}
\cs{clistGet} \meta{comma list} \meta{token list variable}
\end{syntax}
Stores the left-most item from the \meta{comma list} in the
\meta{token list variable} without removing it from the
\meta{comma list}. The \meta{token list variable} is assigned locally.
If the \meta{comma list} is empty the
\meta{token list variable} is set to the marker value \cs{qNoValue}.
\begin{demohigh}
\clistSet \lTmpaClist {two,three,four}
\clistGet \lTmpaClist \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\clistGetT,\clistGetF,\clistGetTF}
\begin{syntax}
\cs{clistGetT} \meta{comma list} \meta{token list variable} \meta{true code}
\cs{clistGetF} \meta{comma list} \meta{token list variable} \meta{false code}
\cs{clistGetTF} \meta{comma list} \meta{token list variable} \meta{true code} \meta{false code}
\end{syntax}
If the \meta{comma list} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{comma list} is non-empty, stores the left-most item from the
\meta{comma list} in the \meta{token list variable} without removing
it from the \meta{comma list}.
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\clistSet \lTmpaClist {two,three,four}
\clistGetTF \lTmpaClist \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\clistPop}
\begin{syntax}
\cs{clistPop} \meta{comma list} \meta{token list variable}
\end{syntax}
Pops the left-most item from a \meta{comma list} into the
\meta{token list variable}, \emph{i.e.} removes the item from the
comma list and stores it in the \meta{token list variable}.
The assignment of the \meta{token list variable} is local.
If the \meta{comma list} is empty the
\meta{token list variable} is set to the marker value \cs{qNoValue}.
\begin{demohigh}
\clistSet \lTmpaClist {two,three,four}
\clistPop \lTmpaClist \lTmpaTl
\clistVarJoin \lTmpaClist {,}
\end{demohigh}
\end{function}

\begin{function}{\clistPopT,\clistPopF,\clistPopTF}
\begin{syntax}
\cs{clistPopT} \meta{comma list} \meta{token list variable} \Arg{true code}
\cs{clistPopF} \meta{comma list} \meta{token list variable} \Arg{false code}
\cs{clistPopTF} \meta{comma list} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{comma list} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{comma list} is non-empty, pops the top item from the
\meta{comma list} in the \meta{token list variable}, \emph{i.e.} removes
the item from the \meta{comma list}.
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\clistSet \lTmpaClist {two,three,four}
\clistPopTF \lTmpaClist \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\clistPush}
\begin{syntax}
\cs{clistPush} \meta{comma list} \Arg{items}
\end{syntax}
Adds the \Arg{items} to the top of the \meta{comma list}.
Spaces are removed from both sides of each item as for any
\texttt{n}-type comma list.
\begin{demohigh}
\clistSet \lTmpaClist {two,three,four}
\clistPush \lTmpaClist {zero,one}
\clistVarJoin \lTmpaClist {|}
\end{demohigh}
\end{function}

\section{Mapping over Comma Lists}

%The functions described in this section apply a specified function
%to each item of a comma list.
%All mappings are done at the current group level, \emph{i.e.} any
%local assignments made by the \meta{function} or \meta{code} discussed
%below remain in effect after the loop.

When the comma list is given explicitly, %as an \texttt{n}-type argument,
spaces are trimmed around each item.
If the result of trimming spaces is empty, the item is ignored.
Otherwise, if the item is surrounded by braces, one set is removed,
and the result is passed to the mapped function. Thus, if the
comma list that is being mapped is \verb*|{a , {{b} }, ,{}, {c},}|
then the arguments passed to the mapped function are
`\verb*|a|', `\verb*|{b} |', an empty argument, and `\verb*|c|'.

When the comma list is given as a variable, spaces
have already been trimmed on input, and items are simply stripped
of one set of braces if any. This case is more efficient than using
explicit comma lists.

%\begin{function}{\clistMapFunction,\clistVarMapFunction}
%\begin{syntax}
%\cs{clistMapFunction} \Arg{comma list} \meta{function}
%\cs{clistVarMapFunction} \meta{comma list} \meta{function}
%\end{syntax}
%Applies \meta{function} to every \meta{item} stored in the
%\meta{comma list}. The \meta{function} receives one argument for
%each iteration. The \meta{items} are returned from left to right.
%The function \cs{clistMapInline} is in general more efficient
%than \cs{clistMapFunction}.
%\end{function}

\begin{function}{\clistMapInline,\clistVarMapInline}
\begin{syntax}
\cs{clistMapInline} \Arg{comma list} \Arg{inline function}
\cs{clistVarMapInline} \meta{comma list} \Arg{inline function}
\end{syntax}
Applies \meta{inline function} to every \meta{item} stored
within the \meta{comma list}. The \meta{inline function} should
consist of code which receives the \meta{item} as \verb|#1|.
The \meta{items} are returned from left to right.
\begin{demohigh}
\IgnoreSpacesOn
\tlClear \lTmpaTl
\clistMapInline {one,two,three} {
  \tlPutRight \lTmpaTl {(#1)}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

\begin{function}{\clistMapVariable,\clistVarMapVariable}
\begin{syntax}
\cs{clistMapVariable} \Arg{comma list} \meta{variable} \Arg{code}
\cs{clistVarMapVariable} \meta{comma list} \meta{variable} \Arg{code}
\end{syntax}
Stores each \meta{item} of the \meta{comma list} in turn in the
(token list) \meta{variable} and applies the \meta{code}.  The
\meta{code} will usually make use of the \meta{variable}, but this
is not enforced.  The assignments to the \meta{variable} are local.
Its value after the loop is the last \meta{item} in the \meta{comma
list}, or its original value if there were no \meta{item}.  The
\meta{items} are returned from left to right.
\begin{demohigh}
\IgnoreSpacesOn
\clistMapVariable {one,two,three} \lTmpiTl {
  \tlPutRight \gTmpaTl {\expWhole {(\lTmpiTl)}}
}
\tlUse \gTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\clistMapTokens,\clistVarMapTokens}
%\begin{syntax}
%\cs{clistMapTokens} \Arg{comma list} \Arg{code}
%\cs{clistVarMapTokens} \meta{clist var} \Arg{code}
%\end{syntax}
%Calls \meta{code} \Arg{item} for every \meta{item} stored in the
%\meta{comma list}. The \meta{code} receives each \meta{item} as a
%trailing brace group.  If the \meta{code} consists of a single
%function this is equivalent to \cs{clistMapFunction} or \cs{clistVarMapFunction}.
%\end{function}

%\begin{function}{\clistMapBreak}
%\begin{syntax}
%\cs{clistMapBreak}
%\end{syntax}
%Used to terminate a clist map function before all
%entries in the \meta{comma list} have been processed. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\clist_map_inline:Nn \l_my_clist
%{
%\str_if_eq:nnTF { #1 } { bingo }
%{ \clist_map_break: }
%{
%Do something useful
%}
%}
%\end{verbatim}
%Use outside of a clist map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before further items are taken
%from the input stream. This depends on the design of the mapping
%function.
%\end{texnote}
%\end{function}
%
%\begin{function}{\clistMapBreakDo}
%\begin{syntax}
%\cs{clistMapBreakDo} \Arg{code}
%\end{syntax}
%Used to terminate a clist map  function before all
%entries in the \meta{comma list} have been processed, inserting
%the \meta{code} after the mapping has ended. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\clist_map_inline:Nn \l_my_clist
%{
%\str_if_eq:nnTF { #1 } { bingo }
%{ \clist_map_break:n { <code> } }
%{
%Do something useful
%}
%}
%\end{verbatim}
%Use outside of a clist map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before the \meta{code} is
%inserted into the input stream.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}

\section{Comma List Conditionals}

\begin{function}{\clistIfExist,\clistIfExistT,\clistIfExistF,\clistIfExistTF}
\begin{syntax}
\cs{clistIfExist} \meta{comma list}
\cs{clistIfExistT} \meta{comma list} \Arg{true code}
\cs{clistIfExistF} \meta{comma list} \Arg{false code}
\cs{clistIfExistTF} \meta{comma list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{comma list} is currently defined.  This does
not check that the \meta{comma list} really is a comma list.
\begin{demohigh}
\clistIfExistTF \lTmpaClist {\prgReturn{Yes}} {\prgReturn{No}}
\clistIfExistTF \lFooUndefinedClist {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\clistIfEmpty,\clistIfEmptyT,\clistIfEmptyF,\clistIfEmptyTF}
\begin{syntax}
\cs{clistIfEmpty} \Arg{comma list}
\cs{clistIfEmptyT} \Arg{comma list} \Arg{true code}
\cs{clistIfEmptyF} \Arg{comma list} \Arg{false code}
\cs{clistIfEmptyTF} \Arg{comma list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{comma list} is empty (containing no items).
The rules for space trimming are as for other \texttt{n}-type
comma-list functions, hence the comma list \verb|{ , ,, }| (without
outer braces) is empty, while \verb|{ ,{},}| (without outer braces)
contains one element, which happens to be empty: the comma-list
is not empty.
\begin{demohigh}
\clistIfEmptyTF {one,two} {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\clistIfEmptyTF { , } {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\clistVarIfEmpty,\clistVarIfEmptyT,\clistVarIfEmptyF,\clistVarIfEmptyTF}
\begin{syntax}
\cs{clistVarIfEmpty} \meta{comma list}
\cs{clistVarIfEmptyT} \meta{comma list} \Arg{true code}
\cs{clistVarIfEmptyF} \meta{comma list} \Arg{false code}
\cs{clistVarIfEmptyTF} \meta{comma list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{comma list} is empty (containing no items).
\begin{demohigh}
\clistSet \lTmpaClist {one,two}
\clistVarIfEmptyTF \lTmpaClist {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\clistClear \lTmpaClist
\clistVarIfEmptyTF \lTmpaClist {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\clistIfIn,\clistIfInT,\clistIfInF,\clistIfInTF}
\begin{syntax}
\cs{clistIfIn} \Arg{comma list} \Arg{item}
\cs{clistIfInT} \Arg{comma list} \Arg{item} \Arg{true code}
\cs{clistIfInF} \Arg{comma list} \Arg{item} \Arg{false code}
\cs{clistIfInTF} \Arg{comma list} \Arg{item} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{item} is present in the \meta{comma list}.
In the case of an \texttt{n}-type \meta{comma list}, the usual rules
of space trimming and brace stripping apply. For example
\begin{demohigh}
\clistIfInTF { a , {b}  , {b} , c } {b} {\prgReturn{Yes}} {\prgReturn{No}}
\clistIfInTF { a , {b}  , {b} , c } {d} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
%\begin{texnote}
%The function may fail if the \meta{item} contains \verb|{|, \verb|}|, or \verb|#|
%(assuming the usual \TeX{} category codes apply).
%\end{texnote}
\end{function}

\begin{function}{\clistVarIfIn,\clistVarIfInT,\clistVarIfInF,\clistVarIfInTF}
\begin{syntax}
\cs{clistVarIfIn} \meta{comma list} \Arg{item}
\cs{clistVarIfInT} \meta{comma list} \Arg{item} \Arg{true code}
\cs{clistVarIfInF} \meta{comma list} \Arg{item} \Arg{false code}
\cs{clistVarIfInTF} \meta{comma list} \Arg{item} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{item} is present in the \meta{comma list}.
In the case of an \texttt{n}-type \meta{comma list}, the usual rules
of space trimming and brace stripping apply.
\begin{demohigh}
\clistSet \lTmpaClist {one,two}
\clistVarIfInTF \lTmpaClist {one} {\prgReturn{Yes}} {\prgReturn{No}}
\clistVarIfInTF \lTmpaClist {three} {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
%\begin{texnote}
%The function may fail if the \meta{item} contains \verb|{|, \verb|}|, or \verb|#|
%(assuming the usual \TeX{} category codes apply).
%\end{texnote}
\end{function}

\chapter{Sequences and Stacks (\texttt{Seq})}

\section{Constant and Scratch Sequences}

\begin{variable}{\cEmptySeq}
Constant that is always empty.
\end{variable}

\begin{variable}{\lTmpaSeq,\lTmpbSeq,\lTmpcSeq,\lTmpiSeq,\lTmpjSeq,\lTmpkSeq}
Scratch sequences for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaSeq,\gTmpbSeq,\gTmpcSeq,\gTmpiSeq,\gTmpjSeq,\gTmpkSeq}
Scratch sequences for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Creating and Using Sequences}

\begin{function}{\seqNew}
\begin{syntax}
\cs{seqNew} \meta{sequence}
\end{syntax}
Creates a new \meta{sequence} or raises an error if the name is
already taken. The declaration is global. The \meta{sequence}
initially contains no items.
\begin{codehigh}
\seqNew \lFooSomeSeq
\end{codehigh}
\end{function}

\begin{function}{\seqConstFromClist}
\begin{syntax}
\cs{seqConstFromClist} \meta{seq var} \Arg{comma-list}
\end{syntax}
Creates a new constant \meta{seq var} or raises an error if the name
is already taken. The \meta{seq var} is set globally to contain the
items in the \meta{comma list}.
\begin{codehigh}
\seqConstFromClist \cFooSomeSeq {one,two,three}
\end{codehigh}
\end{function}

\begin{function}{\seqVarJoin}
\begin{syntax}
\cs{seqVarJoin} \meta{seq var} \Arg{separator}
\end{syntax}
Returns the contents of the \meta{seq var}, with
the \meta{separator} between the items.  If the sequence has
a single item, it is returned with no \meta{separator},
and an empty sequence returns nothing.  An error is raised if
the variable does not exist or if it is invalid.
\begin{demohigh}
\seqSetSplit \lTmpaSeq {|} {a|b|c|{de}|f}
\seqVarJoin \lTmpaSeq { and }
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{items}
%do not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\seqVarJoinExtended}
\begin{syntax}
\cs{seqVarJoinExtended} \meta{seq var} \Arg{separator between two} \Arg{separator between more than two} \Arg{separator between final two}
\end{syntax}
Returns the contents of the \meta{seq var}, with
the appropriate \meta{separator} between the items.  Namely, if the
sequence has more than two items, the \meta{separator between more
than two} is placed between each pair of items except the last,
for which the \meta{separator between final two} is used.  If the
sequence has exactly two items, then they are joined
with the \meta{separator between two} and returned. If the sequence has
a single item, it is returned, and an empty sequence
returns nothing.  An error is raised if the variable does
not exist or if it is invalid.
\begin{demohigh}
\seqSetSplit \lTmpaSeq {|} {a|b|c|{de}|f}
\seqVarJoinExtended \lTmpaSeq { and } {, } {, and }
\end{demohigh}
The first separator argument is not used in this case
because the sequence has more than $2$ items.
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{items}
%do not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\section{Viewing Sequences}

\begin{function}{\seqVarLog}
\begin{syntax}
\cs{seqVarLog} \meta{sequence}
\end{syntax}
Writes the entries in the \meta{sequence} in the log file.
\begin{codehigh}
\seqVarLog \lFooSomeSeq
\end{codehigh}
\end{function}

\begin{function}{\seqVarShow}
\begin{syntax}
\cs{seqVarShow} \meta{sequence}
\end{syntax}
Displays the entries in the \meta{sequence} in the terminal.
\begin{codehigh}
\seqVarShow \lFooSomeSeq
\end{codehigh}
\end{function}

\section{Setting Sequences}

\begin{function}{\seqSetFromClist}
\begin{syntax}
\cs{seqSetFromClist} \meta{sequence} \meta{comma-list}
\end{syntax}
Converts the data in the \meta{comma list} into a \meta{sequence}:
the original \meta{comma list} is unchanged.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,three}
\seqVarJoin \lTmpaSeq { and }
\end{demohigh}
\end{function}

\begin{function}{\seqSetSplit}
\begin{syntax}
\cs{seqSetSplit} \meta{sequence} \Arg{delimiter} \Arg{token list}
\end{syntax}
Splits the \meta{token list} into \meta{items} separated
by \meta{delimiter}, and assigns the result to the \meta{sequence}.
Spaces on both sides of each \meta{item} are ignored,
then one set of outer braces is removed (if any);
this space trimming behaviour is identical to that of
\pkg{Clist} functions. Empty \meta{items} are preserved by
\cs{seqSetSplit}, and can be removed afterwards using
\cs{seqVarRemoveAll} \meta{sequence} \verb|{}|.
The \meta{delimiter} may not contain \verb|{|, \verb|}| or \verb|#|
(assuming \TeX{}'s normal category code r\'egime).
If the \meta{delimiter} is empty, the \meta{token list} is split
into \meta{items} as a \meta{token list}.
%See also \cs{seqSetSplitKeepSpaces}, which omits space stripping.
\begin{demohigh}
\seqSetSplit \lTmpaSeq {,} {1,2,3}
\seqVarJoin \lTmpaSeq { and }
\end{demohigh}
\end{function}

\begin{function}{\seqSetEq}
\begin{syntax}
\cs{seqSetEq} \meta{sequence_1} \meta{sequence_2}
\end{syntax}
Sets the content of \meta{sequence_1} equal to that of
\meta{sequence_2}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,three,four}
\seqSetEq \lTmpbSeq \lTmpaSeq
\seqVarJoin \lTmpbSeq { and }
\end{demohigh}
\end{function}

\begin{function}{\seqClear}
\begin{syntax}
\cs{seqClear} \meta{sequence}
\end{syntax}
Clears all items from the \meta{sequence}.
\begin{codehigh}
\seqClear \lTmpaSeq
\end{codehigh}
\end{function}

\begin{function}{\seqClearNew}
\begin{syntax}
\cs{seqClearNew} \meta{sequence}
\end{syntax}
Ensures that the \meta{sequence} exists globally by applying
\cs{seqNew} if necessary, then applies \cs{seqClear} to leave
the \meta{sequence} empty.
\begin{demohigh}
\seqClearNew \lFooSomeSeq
\seqSetFromClist \lFooSomeSeq {one,two,three}
\seqVarJoin \lFooSomeSeq { and }
\end{demohigh}
\end{function}

\begin{function}{\seqConcat}
\begin{syntax}
\cs{seqConcat} \meta{sequence_1} \meta{sequence_2} \meta{sequence_3}
\end{syntax}
Concatenates the content of \meta{sequence_2} and \meta{sequence_3}
together and saves the result in \meta{sequence_1}. The items in
\meta{sequence_2} are placed at the left side of the new sequence.
\begin{demohigh}
\seqSetFromClist \lTmpbSeq {one,two}
\seqSetFromClist \lTmpcSeq {three,four}
\seqConcat \lTmpaSeq \lTmpbSeq \lTmpcSeq
\seqVarJoin \lTmpaSeq {, }
\end{demohigh}
\end{function}

%\begin{function}{\seqSetSplitKeepSpaces}
%\begin{syntax}
%\cs{seqSetSplitKeepSpaces} \meta{sequence} \Arg{delimiter} \Arg{token list}
%\end{syntax}
%Splits the \meta{token list} into \meta{items} separated
%by \meta{delimiter}, and assigns the result to the \meta{sequence}.
%One set of outer braces is removed (if any) but any surrounding spaces
%are retained: any braces \emph{inside} one or more spaces are
%therefore kept. Empty \meta{items} are preserved by
%\cs{seqSetSplitKeepSpaces}, and can be removed afterwards using
%\cs{seqVarRemoveAll} \meta{sequence} \verb|{}|.
%The \meta{delimiter} may not contain \verb|{|, \verb|}| or \verb|#|
%(assuming \TeX{}'s normal category code r\'egime).
%If the \meta{delimiter} is empty, the \meta{token list} is split
%into \meta{items} as a \meta{token list}.
%%See also \cs{seqSetSplit}, which removes spaces around the delimiters.
%\end{function}

\begin{function}{\seqPutLeft}
\begin{syntax}
\cs{seqPutLeft} \meta{sequence} \Arg{item}
\end{syntax}
Appends the \meta{item} to the left of the \meta{sequence}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two}
\seqPutLeft \lTmpaSeq {zero}
\seqVarJoin \lTmpaSeq { and }
\end{demohigh}
\end{function}

\begin{function}{\seqPutRight}
\begin{syntax}
\cs{seqPutRight} \meta{sequence} \Arg{item}
\end{syntax}
Appends the \meta{item} to the right of the \meta{sequence}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two}
\seqPutRight \lTmpaSeq {three}
\seqVarJoin \lTmpaSeq { and }
\end{demohigh}
\end{function}

\section{Modifying Sequences}

While sequences are normally used as ordered lists, it may be
necessary to modify the content. The functions here may be used
to update sequences, while retaining the order of the unaffected
entries.

\begin{function}{\seqVarRemoveDuplicates}
\begin{syntax}
\cs{seqVarRemoveDuplicates} \meta{sequence}
\end{syntax}
Removes duplicate items from the \meta{sequence}, leaving the
left most copy of each item in the \meta{sequence}.  The \meta{item}
comparison takes place on a token basis, as for \cs{tlIfEqTF}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,one,two,three}
\seqVarRemoveDuplicates \lTmpaSeq
\seqVarJoin \lTmpaSeq {,}
\end{demohigh}
%\begin{texnote}
%This function iterates through every item in the \meta{sequence} and
%does a comparison with the \meta{items} already checked. It is therefore
%relatively slow with large sequences.
%\end{texnote}
\end{function}

\begin{function}{\seqVarRemoveAll}
\begin{syntax}
\cs{seqVarRemoveAll} \meta{sequence} \Arg{item}
\end{syntax}
Removes every occurrence of \meta{item} from the \meta{sequence}.
The \meta{item} comparison takes place on a token basis, as for \cs{tlIfEqTF}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,one,two,three}
\seqVarRemoveAll \lTmpaSeq {two}
\seqVarJoin \lTmpaSeq {,}
\end{demohigh}
\end{function}

\begin{function}{\seqVarReverse}
\begin{syntax}
\cs{seqVarReverse} \meta{sequence}
\end{syntax}
Reverses the order of the items stored in the \meta{sequence}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,one,two,three}
\seqVarReverse \lTmpaSeq
\seqVarJoin \lTmpaSeq {,}
\end{demohigh}
\end{function}

%\begin{function}{\seqVarSort}
%\begin{syntax}
%\cs{seqVarSort} \meta{sequence} \Arg{comparison code}
%\end{syntax}
%Sorts the items in the \meta{sequence} according to the
%\meta{comparison code}, and assigns the result to
%\meta{sequence}. The details of sorting comparison are
%described in Section \ref{sec:l3sort:mech}.
%\end{function}

%\begin{function}{\seqVarShuffle}
%\begin{syntax}
%\cs{seqVarShuffle} \meta{seq var}
%\end{syntax}
%Sets the \meta{seq var} to the result of placing the items of the
%\meta{seq var} in a random order.  Each item is (roughly) as likely
%to end up in any given position.
%\begin{texnote}
%For sequences with more than $13$ items or so, only a small
%proportion of all possible permutations can be reached, because
%the random seed \cs{sys_rand_seed:} only has $28$-bits.  The use
%of \tn{toks} internally means that sequences with more than
%$32767$ or $65535$ items (depending on the engine) cannot be
%shuffled.
%\end{texnote}
%\end{function}

\section{Working with the Contents of Sequences}

\begin{function}{\seqVarCount}
\begin{syntax}
\cs{seqVarCount} \meta{sequence}
\end{syntax}
Returns the number of items in the \meta{sequence}
as an \meta{integer denotation}. The total number of items
in a \meta{sequence} includes those which are empty and duplicates,
\emph{i.e.} every item in a \meta{sequence} is unique.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,three,four}
\seqVarCount \lTmpaSeq
\end{demohigh}
\end{function}

\begin{function}{\seqVarItem}
\begin{syntax}
\cs{seqVarItem} \meta{sequence} \Arg{integer expression}
\end{syntax}
Indexing items in the \meta{sequence} from $1$ at the top (left), this
function evaluates the \meta{integer expression} and returns the
appropriate item from the sequence. If the
\meta{integer expression} is negative, indexing occurs from the
bottom (right) of the sequence. If the \meta{integer expression}
is larger than the number of items in the \meta{sequence} (as
calculated by \cs{seqVarCount}) then the function returns nothing.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,three,four}
\tlSet \lTmpaTl {\seqVarItem \lTmpaSeq {3}}
\tlUse \lTmpaTl
\end{demohigh}
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\seqVarRandItem}
\begin{syntax}
\cs{seqVarRandItem} \meta{seq var}
\end{syntax}
Selects a pseudo-random item of the \meta{sequence}. If the
\meta{sequence} is empty the result is empty.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two,three,four,five,six}
\tlSet \lTmpaTl {\seqVarRandItem \lTmpaSeq}
\tlUse \lTmpaTl
\tlSet \lTmpaTl {\seqVarRandItem \lTmpaSeq}
\tlUse \lTmpaTl
\end{demohigh}
%This is not available in older versions of \XeTeX{}.
%\begin{texnote}
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{item}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\section{Sequences as Stacks}

Sequences can be used as stacks, where data is pushed to and popped
from the top of the sequence. (The left of a sequence is the top, for
performance reasons.) The stack functions for sequences are not
intended to be mixed with the general ordered data functions detailed
in the previous section: a sequence should either be used as an
ordered data type or as a stack, but not in both ways.

\begin{function}{\seqGet}
\begin{syntax}
\cs{seqGet} \meta{sequence} \meta{token list variable}
\end{syntax}
Reads the top item from a \meta{sequence} into the
\meta{token list variable} without removing it from the
\meta{sequence}. The \meta{token list variable} is assigned locally.
If \meta{sequence} is empty the \meta{token list variable} is set to
the special marker \cs{qNoValue}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqGet \lTmpaSeq \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\seqGetT,\seqGetF,\seqGetTF}
\begin{syntax}
\cs{seqGetT} \meta{sequence} \meta{token list variable} \Arg{true code}
\cs{seqGetF} \meta{sequence} \meta{token list variable} \Arg{false code}
\cs{seqGetTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{sequence} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{sequence} is non-empty, stores the top item from a
\meta{sequence} in the \meta{token list variable} without removing it from
the \meta{sequence}. The \meta{token list variable} is assigned locally.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqGetTF \lTmpaSeq \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\seqPop}
\begin{syntax}
\cs{seqPop} \meta{sequence} \meta{token list variable}
\end{syntax}
Pops the top item from a \meta{sequence} into the
\meta{token list variable}. the \meta{token list variable} is assigned locally.
If \meta{sequence} is empty the \meta{token list variable} is set to
the special marker \cs{qNoValue}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqPop \lTmpaSeq \lTmpaTl
\seqVarJoin \lTmpaSeq {,}
\end{demohigh}
\end{function}

\begin{function}{\seqPopT,\seqPopF,\seqPopTF}
\begin{syntax}
\cs{seqPopT} \meta{sequence} \meta{token list variable} \Arg{true code}
\cs{seqPopF} \meta{sequence} \meta{token list variable} \Arg{false code}
\cs{seqPopTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{sequence} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{sequence} is non-empty, pops the top item from the \meta{sequence}
in the \meta{token list variable}, \emph{i.e.} removes the item from the
\meta{sequence}. The \meta{token list variable} is assigned locally.
\begin{demohigh}
\seqPopTF \cEmptySeq \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\seqPush}
\begin{syntax}
\cs{seqPush} \meta{sequence} \Arg{item}
\end{syntax}
Adds the \Arg{item} to the top of the \meta{sequence}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqPush \lTmpaSeq {one}
\seqVarJoin \lTmpaSeq {|}
\end{demohigh}
You can only push one item to the \meta{sequence} with \cs{seqPush},
which is different from \cs{ClistPush}.
\end{function}

\section{Recovering Items from Sequences}

Items can be recovered from either the left or the right of sequences.
For implementation reasons, the actions at the left of the sequence are
faster than those acting on the right. These functions all assign the
recovered material locally.

\begin{function}{\seqGetLeft}
\begin{syntax}
\cs{seqGetLeft} \meta{sequence} \meta{token list variable}
\end{syntax}
Stores the left-most item from a \meta{sequence} in the
\meta{token list variable} without removing it from the
\meta{sequence}. The \meta{token list variable} is assigned locally.
If \meta{sequence} is empty the \meta{token list variable}
is set to the special marker \cs{qNoValue}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqGetLeft \lTmpaSeq \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\seqGetLeftT,\seqGetLeftF,\seqGetLeftTF}
\begin{syntax}
\cs{seqGetLeftT} \meta{sequence} \meta{token list variable} \Arg{true code}
\cs{seqGetLeftF} \meta{sequence} \meta{token list variable} \Arg{false code}
\cs{seqGetLeftTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{sequence} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{sequence} is non-empty, stores the left-most item from the
\meta{sequence}
in the \meta{token list variable} without removing it from the
\meta{sequence}, then leaves the \meta{true code} in the input stream.
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqGetLeftTF \lTmpaSeq \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\seqGetRight}
\begin{syntax}
\cs{seqGetRight} \meta{sequence} \meta{token list variable}
\end{syntax}
Stores the right-most item from a \meta{sequence} in the
\meta{token list variable} without removing it from the
\meta{sequence}. The \meta{token list variable} is assigned locally.
If \meta{sequence} is empty the \meta{token list variable}
is set to the special marker \cs{qNoValue}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqGetRight \lTmpaSeq \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\seqGetRightT,\seqGetRightF,\seqGetRightTF}
\begin{syntax}
\cs{seqGetRightT} \meta{sequence} \meta{token list variable} \Arg{true code}
\cs{seqGetRightF} \meta{sequence} \meta{token list variable} \Arg{false code}
\cs{seqGetRightTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{sequence} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{sequence} is non-empty, stores the right-most item from the
\meta{sequence}
in the \meta{token list variable} without removing it from the
\meta{sequence}, then leaves the \meta{true code} in the input stream.
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqGetRightTF \lTmpaSeq \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\seqPopLeft}
\begin{syntax}
\cs{seqPopLeft} \meta{sequence} \meta{token list variable}
\end{syntax}
Pops the left-most item from a \meta{sequence} into the
\meta{token list variable}, \emph{i.e.} removes the item from the
sequence and stores it in the \meta{token list variable}.
The assignment of the \meta{token list variable} is local.
If \meta{sequence} is empty the \meta{token list variable}
is set to the special marker \cs{qNoValue}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqPopLeft \lTmpaSeq \lTmpaTl
\seqVarJoin \lTmpaSeq {,}
\end{demohigh}
\end{function}

\begin{function}{\seqPopLeftT,\seqPopLeftF,\seqPopLeftTF}
\begin{syntax}
\cs{seqPopLeftT} \meta{sequence} \meta{token list variable} \Arg{true code}
\cs{seqPopLeftF} \meta{sequence} \meta{token list variable} \Arg{false code}
\cs{seqPopLeftTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{sequence} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{sequence} is non-empty, pops the left-most item from the \meta{sequence}
in the \meta{token list variable}, \emph{i.e.} removes the item from the
\meta{sequence}, then leaves the \meta{true code} in the input stream.
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\seqPopLeftTF \cEmptySeq \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\seqPopRight}
\begin{syntax}
\cs{seqPopRight} \meta{sequence} \meta{token list variable}
\end{syntax}
Pops the right-most item from a \meta{sequence} into the
\meta{token list variable}, \emph{i.e.} removes the item from the
sequence and stores it in the \meta{token list variable}.
The assignment of the \meta{token list variable} is local.
If \meta{sequence} is empty the \meta{token list variable}
is set to the special marker \cs{qNoValue}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {two,three,four}
\seqPopRight \lTmpaSeq \lTmpaTl
\seqVarJoin \lTmpaSeq {,}
\end{demohigh}
\end{function}

\begin{function}{\seqPopRightT,\seqPopRightF,\seqPopRightTF}
\begin{syntax}
\cs{seqPopRightT} \meta{sequence} \meta{token list variable} \Arg{true code}
\cs{seqPopRightF} \meta{sequence} \meta{token list variable} \Arg{false code}
\cs{seqPopRightTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{sequence} is empty, leaves the \meta{false code} in the
input stream.  The value of the \meta{token list variable} is
not defined in this case and should not be relied upon.  If the
\meta{sequence} is non-empty, pops the right-most item from the \meta{sequence}
in the \meta{token list variable}, \emph{i.e.} removes the item from the
\meta{sequence}, then leaves the \meta{true code} in the input stream.
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\seqPopRightTF \cEmptySeq \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\section{Mapping over Sequences}

%All mappings are done at the current group level, \emph{i.e.} any
%local assignments made by the \meta{function} or \meta{code} discussed
%below remain in effect after the loop.

%\begin{function}{\seqVarMapFunction}
%\begin{syntax}
%\cs{seqVarMapFunction} \meta{sequence} \meta{function}
%\end{syntax}
%Applies \meta{function} to every \meta{item} stored in the
%\meta{sequence}. The \meta{function} will receive one argument for
%each iteration. The \meta{items} are returned from left to right.
%To pass further arguments to the \meta{function}, see \cs{seqVarMapTokens}.
%The function \cs{seqVarMapInline} is faster than
%\cs{seqVarMapFunction} for sequences with more than about $10$ items.
%\end{function}

\begin{function}{\seqVarMapInline}
\begin{syntax}
\cs{seqVarMapInline} \meta{sequence} \Arg{inline function}
\end{syntax}
Applies \meta{inline function} to every \meta{item} stored
within the \meta{sequence}. The \meta{inline function} should
consist of code which will receive the \meta{item} as \verb|#1|.
The \meta{items} are returned from left to right.
\begin{demohigh}
\IgnoreSpacesOn
\seqSetFromClist \lTmpkSeq {one,two,three}
\tlClear \lTmpaTl
\seqVarMapInline \lTmpkSeq {
  \tlPutRight \lTmpaTl {(#1)}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\seqVarMapTokens}
%\begin{syntax}
%\cs{seqVarMapTokens} \meta{sequence} \Arg{code}
%\end{syntax}
%Analogue of \cs{seqVarMapFunction} which maps several tokens
%instead of a single function.  The \meta{code} receives each item in
%the \meta{sequence} as a trailing brace group. For instance,
%\begin{verbatim}
%\seqVarMapTokens \lMySeq { \prgReplicate { 2 } }
%\end{verbatim}
%expands to twice each item in the \meta{sequence}: for each item in
%\verb|\l_my_seq| the function \cs{PrgReplicate} receives \verb|2| and
%\meta{item} as its two arguments.  The function
%\cs{seqVarMapInline} is typically faster but it is not expandable.
%\end{function}

\begin{function}{\seqVarMapVariable}
\begin{syntax}
\cs{seqVarMapVariable} \meta{sequence} \meta{variable} \Arg{code}
\end{syntax}
Stores each \meta{item} of the \meta{sequence} in turn in the (token
list) \meta{variable} and applies the \meta{code}.  The \meta{code}
will usually make use of the \meta{variable}, but this is not
enforced.  The assignments to the \meta{variable} are local.  Its
value after the loop is the last \meta{item} in the \meta{sequence},
or its original value if the \meta{sequence} is empty.  The
\meta{items} are returned from left to right.
\begin{demohigh}
\IgnoreSpacesOn
\intZero \lTmpaInt
\seqSetFromClist \lTmpaSeq {1,3,7}
\seqVarMapVariable \lTmpaSeq \lTmpiTl {
  \intAdd \lTmpaInt {\lTmpiTl*\lTmpiTl}
}
\intUse \lTmpaInt
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\seqVarMapIndexedFunction}
%\begin{syntax}
%\cs{seqVarMapIndexedFunction} \meta{seq var} \meta{function}
%\end{syntax}
%Applies \meta{function} to every entry in the \meta{sequence
%variable}.  The \meta{function} should have signature |:nn|.  It
%receives two arguments for each iteration: the \meta{index} (namely
%\verb|1| for the first entry, then \verb|2| and so on) and the \meta{item}.
%\end{function}

%\begin{function}{\seqVarMapIndexedInline}
%\begin{syntax}
%\cs{seqVarMapIndexedInline} \meta{seq var} \Arg{inline function}
%\end{syntax}
%Applies \meta{inline function} to every entry in the \meta{sequence
%variable}.  The \meta{inline function} should consist of code which
%receives the \meta{index} (namely \verb|1| for the first entry, then \verb|2|
%and so on) as \verb|#1| and the \meta{item} as \verb|#2|.
%\end{function}

%\begin{function}{\seqMapBreak}
%\begin{syntax}
%\cs{seqMapBreak}
%\end{syntax}
%Used to terminate a seq map function before all
%entries in the \meta{sequence} have been processed. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\seq_map_inline:Nn \l_my_seq
%{
%\str_if_eq:nnTF { #1 } { bingo }
%{ \seq_map_break: }
%{
%Do something useful
%}
%}
%\end{verbatim}
%Use outside of a seq map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before further items are taken
%from the input stream. This depends on the design of the mapping
%function.
%\end{texnote}
%\end{function}

%\begin{function}{\seqMapBreakDo}
%\begin{syntax}
%\cs{seqMapBreakDo} \Arg{code}
%\end{syntax}
%Used to terminate a seq map function before all
%entries in the \meta{sequence} have been processed, inserting
%the \meta{code} after the mapping has ended. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\seq_map_inline:Nn \l_my_seq
%{
%\str_if_eq:nnTF { #1 } { bingo }
%{ \seq_map_break:n { <code> } }
%{
%Do something useful
%}
%}
%\end{verbatim}
%Use outside of a seq map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before the \meta{code} is
%inserted into the input stream.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}

%\begin{function}
%{\seq_set_map:NNn, \seq_gset_map:NNn}
%\begin{syntax}
%\cs{seq_set_map:NNn} \meta{sequence_1} \meta{sequence_2} \Arg{inline function}
%\end{syntax}
%Applies \meta{inline function} to every \meta{item} stored
%within the \meta{sequence_2}. The \meta{inline function} should
%consist of code which will receive the \meta{item} as \verb|#1|.
%The sequence resulting applying \meta{inline function} to each
%\meta{item} is assigned to \meta{sequence_1}.
%\begin{texnote}
%Contrarily to other mapping functions, \cs{seq_map_break:} cannot
%be used in this function, and would lead to low-level \TeX{} errors.
%\end{texnote}
%\end{function}

%\begin{function}[added = 2020-07-16]
%{\seq_set_map_x:NNn, \seq_gset_map_x:NNn}
%\begin{syntax}
%\cs{seq_set_map_x:NNn} \meta{sequence_1} \meta{sequence_2} \Arg{inline function}
%\end{syntax}
%Applies \meta{inline function} to every \meta{item} stored
%within the \meta{sequence_2}. The \meta{inline function} should
%consist of code which will receive the \meta{item} as \verb|#1|.
%The sequence resulting from \texttt{x}-expanding
%\meta{inline function} applied to each \meta{item}
%is assigned to \meta{sequence_1}. As such, the code
%in \meta{inline function} should be expandable.
%\begin{texnote}
%Contrarily to other mapping functions, \cs{seq_map_break:} cannot
%be used in this function, and would lead to low-level \TeX{} errors.
%\end{texnote}
%\end{function}

\section{Sequence Conditionals}

\begin{function}{\seqIfExist,\seqIfExistT,\seqIfExistF,\seqIfExistTF}
\begin{syntax}
\cs{seqIfExist} \meta{sequence}
\cs{seqIfExistT} \meta{sequence} \Arg{true code}
\cs{seqIfExistF} \meta{sequence} \Arg{false code}
\cs{seqIfExistTF} \meta{sequence} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{sequence} is currently defined.  This does not
check that the \meta{sequence} really is a sequence variable.
\begin{demohigh}
\seqIfExistTF \lTmpaSeq {\prgReturn{Yes}} {\prgReturn{No}}
\seqIfExistTF \lFooUndefinedSeq {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\seqVarIfEmpty,\seqVarIfEmptyT,\seqVarIfEmptyF,\seqVarIfEmptyTF}
\begin{syntax}
\cs{seqVarIfEmpty} \meta{sequence}
\cs{seqVarIfEmptyT} \meta{sequence} \Arg{true code}
\cs{seqVarIfEmptyF} \meta{sequence} \Arg{false code}
\cs{seqVarIfEmptyTF} \meta{sequence} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{sequence} is empty (containing no items).
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two}
\seqVarIfEmptyTF \lTmpaSeq {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\seqClear \lTmpaSeq
\seqVarIfEmptyTF \lTmpaSeq {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\seqVarIfIn,\seqVarIfInT,\seqVarIfInF,\seqVarIfInTF}
\begin{syntax}
\cs{seqVarIfIn} \meta{sequence} \Arg{item}
\cs{seqVarIfInT} \meta{sequence} \Arg{item} \Arg{true code}
\cs{seqVarIfInF} \meta{sequence} \Arg{item} \Arg{false code}
\cs{seqVarIfInTF} \meta{sequence} \Arg{item} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{item} is present in the \meta{sequence}.
\begin{demohigh}
\seqSetFromClist \lTmpaSeq {one,two}
\seqVarIfInTF \lTmpaSeq {one} {\prgReturn{Yes}} {\prgReturn{Not}}
\seqVarIfInTF \lTmpaSeq {three} {\prgReturn{Yes}} {\prgReturn{Not}}
\end{demohigh}
\end{function}

\chapter{Property Lists (\texttt{Prop})}

\LaTeX3 implements a \enquote{property list} data type, which contain
an unordered list of entries each of which consists of a \meta{key} and
an associated \meta{value}. The \meta{key} and \meta{value} may both
be any \meta{balanced text}, the \meta{key} is processed using
\cs{tlToStr}, meaning that category codes are ignored. It is possible to
map functions to property lists such that the function is applied to every
key--value pair within the list.

Each entry in a property list must have a unique \meta{key}: if an entry is
added to a property list which already contains the \meta{key} then the new
entry overwrites the existing one. The \meta{keys} are compared on a
string basis, using the same method as \cs{strIfEq}.

%Property lists are intended for storing key-based information for use within
%code.  This is in contrast to key--value lists, which are a form of
%\emph{input} parsed by the \pkg{l3keys} module.

\section{Constant and Scratch Sequences}

\begin{variable}{\cEmptyProp}
Constant that is always empty.
\end{variable}

\begin{variable}{\lTmpaProp,\lTmpbProp,\lTmpcProp,\lTmpiProp,\lTmpjProp,\lTmpkProp}
Scratch property lists for local assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaProp,\gTmpbProp,\gTmpcProp,\gTmpiProp,\gTmpjProp,\gTmpkProp}
Scratch property lists for global assignment. These are never used by
the \verb!functional! package, and so are safe for use with any
function. However, they may be overwritten by other
code and so should only be used for short-term storage.
\end{variable}

\section{Creating and Using Property Lists}

\begin{function}{\propNew}
\begin{syntax}
\cs{propNew} \meta{property list}
\end{syntax}
Creates a new \meta{property list} or raises an error if the name is
already taken. The declaration is global. The \meta{property list}
initially contains no entries.
\begin{codehigh}
\propNew \lFooSomeProp
\end{codehigh}
\end{function}

\begin{function}{\propConstFromKeyval}
\begin{syntax}
\cs{propConstFromKeyval} \meta{prop var}
~ \{
~ ~ \meta{key1} \verb|=| \meta{value1} \verb|,|
~ ~ \meta{key2} \verb|=| \meta{value2} \verb|,| $\cdots$
~ \}
\end{syntax}
Creates a new constant \meta{prop var} or raises an error if the
name is already taken. The \meta{prop var} is set globally to
contain key--value pairs given in the second argument, processed in
the way described for \cs{propSetFromKeyval}.  If duplicate
keys appear only the last of the values is kept.
This function correctly detects the \verb|=| and \verb|,| signs provided they
have the standard category code $12$ or they are active.
\begin{codehigh}
\propConstFromKeyval \cFooSomeProp {key1=one,key2=two,key3=three}
\end{codehigh}
%Notice that in contrast to most keyval lists (\emph{e.g.} those in
%\pkg{l3keys}), each key here \emph{must} be followed with an \texttt{=} sign.
\end{function}

\begin{function}{\propToKeyval}
\begin{syntax}
\cs{propToKeyval} \meta{property list}
\end{syntax}
Returns the \meta{property list} in a key--value notation. Keep in mind
that a \meta{property list} is \emph{unordered}, while key--value interfaces
don't necessarily are, so this can't be used for arbitrary interfaces.
%\begin{texnote}
%The result is returned within the \tn{unexpanded} primitive
%(\cs{exp_not:n}), which means that the key--value list does not expand
%further when appearing in an \texttt{x}-type or \texttt{e}-type argument expansion.
%It also needs exactly two steps of expansion.
%\end{texnote}
\begin{codehigh}
\propToKeyval \lTmpaProp
\end{codehigh}
\end{function}

\section{Viewing Property Lists}

\begin{function}{\propVarLog}
\begin{syntax}
\cs{propVarLog} \meta{property list}
\end{syntax}
Writes the entries in the \meta{property list} in the log file.
\begin{codehigh}
\propVarLog \lTmpaProp
\end{codehigh}
\end{function}

\begin{function}{\propVarShow}
\begin{syntax}
\cs{propVarShow} \meta{property list}
\end{syntax}
Displays the entries in the \meta{property list} in the terminal.
\begin{codehigh}
\propVarShow \lTmpaProp
\end{codehigh}
\end{function}

\section{Setting Property Lists}

\begin{function}{\propSetFromKeyval}
\begin{syntax}
\cs{propSetFromKeyval} \meta{prop var}
\{
~ \meta{key1} \verb|=| \meta{value1} \verb|,|
~ \meta{key2} \verb|=| \meta{value2} \verb|,| $\cdots$
\}
\end{syntax}
Sets \meta{prop var} to contain key--value pairs given in the second
argument.  If duplicate keys appear only the last of the values is kept.

Spaces are trimmed around every \meta{key} and every \meta{value},
and if the result of trimming spaces consists of a single brace
group then a set of outer braces is removed.  This enables both the
\meta{key} and the \meta{value} to contain spaces, commas or equal
signs.  The \meta{key} is then processed by \cs{tlToStr}.
This function correctly detects the \verb|=| and \verb|,| signs provided they
have the standard category code $12$ or they are active.
\begin{codehigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\end{codehigh}
%Notice that in contrast to most keyval lists (\emph{e.g.} those in
%\pkg{l3keys}), each key here \emph{must} be followed with an \texttt{=} sign.
\end{function}

\begin{function}{\propSetEq}
\begin{syntax}
\cs{propSetEq} \meta{property list_1} \meta{property list_2}
\end{syntax}
Sets the content of \meta{property list_1} equal to that of
\meta{property list_2}.
\begin{codehigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propSetEq \lTmpbProp \lTmpaProp
\propVarLog \lTmpbProp
\end{codehigh}
\end{function}

\begin{function}{\propClear}
\begin{syntax}
\cs{propClear} \meta{property list}
\end{syntax}
Clears all entries from the \meta{property list}.
\begin{codehigh}
\propClear \lTmpaProp
\end{codehigh}
\end{function}

\begin{function}{\propClearNew}
\begin{syntax}
\cs{propClearNew} \meta{property list}
\end{syntax}
Ensures that the \meta{property list} exists globally by applying \cs{propNew}
if necessary, then applies \cs{propClear} to leave the list empty.
\begin{codehigh}
\propClearNew \lFooSomeProp
\end{codehigh}
\end{function}

\begin{function}{\propConcat}
\begin{syntax}
\cs{propConcat} \meta{prop var_1} \meta{prop var_2} \meta{prop var_3}
\end{syntax}
Combines the key--value pairs of \meta{prop var_2} and
\meta{prop var_3}, and saves the result in \meta{prop var_1}.  If a
key appears in both \meta{prop var_2} and \meta{prop var_3} then the
last value, namely the value in \meta{prop var_3} is kept.
\begin{codehigh}
\propSetFromKeyval \lTmpbProp {key1=one,key2=two}
\propSetFromKeyval \lTmpcProp {key3=three,key4=four}
\propConcat \lTmpaProp \lTmpbProp \lTmpcProp
\propVarLog \lTmpaProp
\end{codehigh}
\end{function}

\begin{function}{\propPut}
\begin{syntax}
\cs{propPut} \meta{property list} \Arg{key} \Arg{value}
\end{syntax}
Adds an entry to the \meta{property list} which may be accessed
using the \meta{key} and which has \meta{value}. If the \meta{key}
is already present in the \meta{property list}, the existing entry
is overwritten by the new \meta{value}. Both the \meta{key} and
\meta{value} may contain any \meta{balanced text}. The \meta{key} is
stored after processing with \cs{tlToStr}, meaning that category
codes are ignored.
\begin{codehigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\propPut \lTmpaProp {key1} {newone}
\propVarLog \lTmpaProp
\end{codehigh}
\end{function}

\begin{function}{\propPutIfNew}
\begin{syntax}
\cs{propPutIfNew} \meta{property list} \Arg{key} \Arg{value}
\end{syntax}
If the \meta{key} is present in the \meta{property list} then no
action is taken. Otherwise, a new entry is added as described for
\cs{propPut}.
\begin{codehigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\propPutIfNew \lTmpaProp {key1} {newone}
\propVarLog \lTmpaProp
\end{codehigh}
\end{function}

\begin{function}{\propPutFromKeyval}
\begin{syntax}
\cs{propPutFromKeyval} \meta{prop var}
\{
~ \meta{key1} \verb|=| \meta{value1} \verb|,|
~ \meta{key2} \verb|=| \meta{value2} \verb|,| $\cdots$
\}
\end{syntax}
Updates the \meta{prop var} by adding entries for each key--value
pair given in the second argument.  The addition is done through
\cs{propPut}, hence if the \meta{prop var} already contains
some of the keys, the corresponding values are discarded and
replaced by those given in the key--value list.  If duplicate keys
appear in the key--value list then only the last of the values is kept.
\begin{codehigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\propPutFromKeyval \lTmpaProp {key1=newone,key3=three}
\propVarLog \lTmpaProp
\end{codehigh}
%The function is equivalent to storing the key--value pairs in a
%temporary property variable using \cs{propSetFromKeyval}, then
%combining \meta{prop var} with the temporary variable using
%\cs{propConcat}.  In particular, the \meta{keys} and
%\meta{values} are space-trimmed and unbraced as described in
%\cs{propSetFromKeyval}. This function correctly detects
%the \verb|=| and \verb|,| signs provided they
%have the standard category code $12$ or they are active.
\end{function}

\begin{function}{\propVarRemove}
\begin{syntax}
\cs{propVarRemove} \meta{property list} \Arg{key}
\end{syntax}
Removes the entry listed under \meta{key} from the
\meta{property list}.  If the \meta{key} is
not found in the \meta{property list} no change occurs,
\emph{i.e} there is no need to test for the existence of a key before
deleting it.
\begin{codehigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propVarRemove \lTmpaProp {key2}
\propVarLog \lTmpaProp
\end{codehigh}
\end{function}

\section{Recovering Values from Property Lists}

\begin{function}{\propVarCount}
\begin{syntax}
\cs{propVarCount} \meta{property list}
\end{syntax}
Returns the number of key--value pairs in the \meta{property list}
as an \meta{integer denotation}.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propVarCount \lTmpaProp
\end{demohigh}
\end{function}

\begin{function}{\propVarItem}
\begin{syntax}
\cs{propVarItem} \meta{property list} \Arg{key}
\end{syntax}
Returns the \meta{value} corresponding to the \meta{key} in
the \meta{property list}. If the \meta{key} is missing,
nothing is returned.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\tlSet \lTmpaTl {\propVarItem \lTmpaProp {key2}}
\tlUse \lTmpaTl
\end{demohigh}
%\begin{texnote}
%This function is slower than the non-expandable analogue
%\cs{prop_get:NnN}.
%The result is returned within the \tn{unexpanded}
%primitive (\cs{exp_not:n}), which means that the \meta{value}
%does not expand further when appearing in an \texttt{x}-type
%or \texttt{e}-type argument expansion.
%\end{texnote}
\end{function}

\begin{function}{\propGet}
\begin{syntax}
\cs{propGet} \meta{property list} \Arg{key} \meta{token list variable}
\end{syntax}
Recovers the \meta{value} stored with \meta{key} from the \meta{property list},
and places this in the \meta{token list variable}.
If the \meta{key} is not found in the
\meta{property list} then the \meta{token list variable} is set
to the special marker \cs{qNoValue}.
The assignment of the \meta{token list variable} is local.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propGet \lTmpaProp {key2} \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
\end{function}

\begin{function}{\propGetT,\propGetF,\propGetTF}
\begin{syntax}
\cs{propGetT} \meta{property list} \Arg{key} \meta{token list variable} \Arg{true code}
\cs{propGetF} \meta{property list} \Arg{key} \meta{token list variable} \Arg{false code}
\cs{propGetTF} \meta{property list} \Arg{key} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{key} is not present in the \meta{property list}, leaves
the \meta{false code} in the input stream.  The value of the
\meta{token list variable} is not defined in this case and should
not be relied upon.  If the \meta{key} is present in the
\meta{property list}, stores the corresponding \meta{value} in the
\meta{token list variable} without removing it from the
\meta{property list}, then leaves the \meta{true code} in the input
stream.  The \meta{token list variable} is assigned locally.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propGetTF \lTmpaProp {key2} \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\propPop}
\begin{syntax}
\cs{propPop} \meta{property list} \Arg{key} \meta{token list variable}
\end{syntax}
Recovers the \meta{value} stored with \meta{key} from the \meta{property list},
and places this in the \meta{token list variable}.
If the \meta{key} is not found in the
\meta{property list} then the \meta{token list variable} is set
to the special marker \cs{qNoValue}.
The \meta{key} and \meta{value} are then deleted from the property list.
The assignment of the \meta{token list variable} is local.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propPop \lTmpaProp {key2} \lTmpaTl
Pop: \tlUse \lTmpaTl.
Count: \propVarCount \lTmpaProp.
\end{demohigh}
\end{function}

\begin{function}{\propPopT,\propPopF,\propPopTF}
\begin{syntax}
\cs{propPopT} \meta{property list} \Arg{key} \meta{token list variable} \Arg{true code}
\cs{propPopF} \meta{property list} \Arg{key} \meta{token list variable} \Arg{false code}
\cs{propPopTF} \meta{property list} \Arg{key} \meta{token list variable} \Arg{true code} \Arg{false code}
\end{syntax}
If the \meta{key} is not present in the \meta{property list}, leaves
the \meta{false code} in the input stream.  The value of the
\meta{token list variable} is not defined in this case and should
not be relied upon.  If the \meta{key} is present in
the \meta{property list}, pops the corresponding \meta{value}
in the \meta{token list variable}, \emph{i.e.} removes the item from
The \meta{token list variable} is assigned locally.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two,key3=three}
\propPopTF \lTmpaProp {key2} \lTmpaTl {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\section{Mapping over property lists}

%All mappings are done at the current group level, \emph{i.e.} any
%local assignments made by the \meta{function} or \meta{code} discussed
%below remain in effect after the loop.

%\begin{function}{\propVarMapFunction}
%\begin{syntax}
%\cs{propVarMapFunction} \meta{property list} \meta{function}
%\end{syntax}
%Applies \meta{function} to every \meta{entry} stored in the
%\meta{property list}. The \meta{function} receives two arguments for
%each iteration: the \meta{key} and associated \meta{value}.
%The order in which \meta{entries} are returned is not defined and
%should not be relied upon.
%To pass further arguments to the \meta{function}, see
%\cs{prop_map_tokens:Nn}.
%\end{function}

\begin{function}{\propVarMapInline}
\begin{syntax}
\cs{propVarMapInline} \meta{property list} \Arg{inline function}
\end{syntax}
Applies \meta{inline function} to every \meta{entry} stored
within the \meta{property list}. The \meta{inline function} should
consist of code which receives the \meta{key} as \verb|#1| and the
\meta{value} as \verb|#2|.
The order in which \meta{entries} are returned is not defined and
should not be relied upon.
\begin{demohigh}
\IgnoreSpacesOn
\propSetFromKeyval \lTmpkProp {key1=one,key2=two,key3=three}
\tlClear \lTmpaTl
\propVarMapInline \lTmpkProp {
  \tlPutRight \lTmpaTl {(#1=#2)}
}
\tlUse \lTmpaTl
\IgnoreSpacesOff
\end{demohigh}
\end{function}

%\begin{function}{\propVarMapTokens}
%\begin{syntax}
%\cs{propVarMapTokens} \meta{property list} \Arg{code}
%\end{syntax}
%Analogue of \cs{propVarMapFunction} which maps several tokens
%instead of a single function.  The \meta{code} receives each
%key--value pair in the \meta{property list} as two trailing brace
%groups. For instance,
%\begin{verbatim}
%\propVarMapTokens \lMyProp { \strIfEqT { mykey } }
%\end{verbatim}
%expands to the value corresponding to \texttt{mykey}: for each
%pair in \verb|\lMyProp| the function \cs{strIfEqT} receives
%\texttt{mykey}, the \meta{key} and the \meta{value} as its three
%arguments. For that specific task, \cs{propVarItem} is faster.
%\end{function}

%\begin{function}{\propMapBreak}
%\begin{syntax}
%\cs{propMapBreak}
%\end{syntax}
%Used to terminate a prop map function before all
%entries in the \meta{property list} have been processed. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\prop_map_inline:Nn \l_my_prop
%{
%\str_if_eq:nnTF { #1 } { bingo }
%{ \prop_map_break: }
%{
%Do something useful
%}
%}
%\end{verbatim}
%Use outside of a prop map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before further items are taken
%from the input stream. This depends on the design of the mapping
%function.
%\end{texnote}
%\end{function}

%\begin{function}{\propMapBreakDo}
%\begin{syntax}
%\cs{propMapBreakDo} \Arg{code}
%\end{syntax}
%Used to terminate a prop map function before all
%entries in the \meta{property list} have been processed, inserting
%the \meta{code} after the mapping has ended. This
%normally takes place within a conditional statement, for example
%\begin{verbatim}
%\prop_map_inline:Nn \l_my_prop
%{
%\str_if_eq:nnTF { #1 } { bingo }
%{ \prop_map_break:n { <code> } }
%{
%Do something useful
%}
%}
%\end{verbatim}
%Use outside of a prop map scenario leads to low
%level \TeX{} errors.
%\begin{texnote}
%When the mapping is broken, additional tokens may be inserted
%before the \meta{code} is
%inserted into the input stream.
%This depends on the design of the mapping function.
%\end{texnote}
%\end{function}

\section{Property List Conditionals}

\begin{function}{\propIfExist,\propIfExistT,\propIfExistF,\propIfExistTF}
\begin{syntax}
\cs{propIfExist} \meta{property list}
\cs{propIfExistT} \meta{property list} \Arg{true code}
\cs{propIfExistF} \meta{property list} \Arg{false code}
\cs{propIfExistTF} \meta{property list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{property list} is currently defined.  This does not
check that the \meta{property list} really is a property list variable.
\begin{demohigh}
\propIfExistTF \lTmpaProp {\prgReturn{Yes}} {\prgReturn{No}}
\propIfExistTF \lFooUndefinedProp {\prgReturn{Yes}} {\prgReturn{No}}
\end{demohigh}
\end{function}

\begin{function}{\propVarIfEmpty,\propVarIfEmptyT,\propVarIfEmptyF,\propVarIfEmptyTF}
\begin{syntax}
\cs{propVarIfEmpty} \meta{property list}
\cs{propVarIfEmptyT} \meta{property list} \Arg{true code}
\cs{propVarIfEmptyF} \meta{property list} \Arg{false code}
\cs{propVarIfEmptyTF} \meta{property list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{property list} is empty (containing no entries).
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\propVarIfEmptyTF \lTmpaProp {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\propClear \lTmpaProp
\propVarIfEmptyTF \lTmpaProp {\prgReturn{Empty}} {\prgReturn{NonEmpty}}
\end{demohigh}
\end{function}

\begin{function}{\propVarIfIn,\propVarIfInT,\propVarIfInF,\propVarIfInTF}
\begin{syntax}
\cs{propVarIfIn} \meta{property list} \Arg{key}
\cs{propVarIfInT} \meta{property list} \Arg{key} \Arg{true code}
\cs{propVarIfInF} \meta{property list} \Arg{key} \Arg{false code}
\cs{propVarIfInTF} \meta{property list} \Arg{key} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{key} is present in the \meta{property list},
making the comparison using the method described by \cs{strIfEqTF}.
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\propVarIfInTF \lTmpaProp {key1} {\prgReturn{Yes}} {\prgReturn{Not}}
\propVarIfInTF \lTmpaProp {key3} {\prgReturn{Yes}} {\prgReturn{Not}}
\end{demohigh}
%\begin{texnote}
%This function iterates through every key--value pair in the
%\meta{property list} and is therefore slower than using \cs{propGetTF}.
%\end{texnote}
\end{function}

\chapter{Regular Expressions (\texttt{Regex})}

This module provides regular expression testing,
extraction of submatches, splitting, and replacement, all acting
on token lists. The syntax of regular expressions is mostly a subset
of the \textsc{pcre} syntax (and very close to \textsc{posix}),
with some additions
due to the fact that \TeX{} manipulates tokens rather than characters.
For performance reasons, only a limited set of features are implemented.
Notably, back-references are not supported.

Let us give a few examples. The following example replace the first
occurrence of \enquote{\texttt{at}} with \enquote{\texttt{is}}
in the token list variable \cs{lTmpaTl}.
\begin{demohigh}
\tlSet \lTmpaTl {That cat.}
\regexReplaceOnce {at} {is} \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
A more complicated example is
a pattern to emphasize each word and add a comma after it:
\begin{demohigh}
\tlSet \lTmpaTl {That cat.}
\regexReplaceAll {\w+} {\c{underline} \cB\{ \0 \cE\} ,} \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}
The |\w| sequence represents any \enquote{word} character, and |+|
indicates that the |\w| sequence should be repeated as many times as
possible (at least once), hence matching a word in the input token
list. In the replacement text, |\0| denotes the full match (here, a
word).  The command |\underline| is inserted using |\c{underline}|,
and its argument |\0| is put between braces |\cB\{| and |\cE\}|.

If a regular expression is to be used several times,
it can be compiled once, and stored in a regex
variable using \cs{regexSet}. For example,
\begin{codehigh}
\regexNew \lFooRegex
\regexSet \lFooRegex {\c{begin} \cB. (\c[^BE].*) \cE.}
\end{codehigh}
stores in \cs{lFooRegex} a regular expression which matches the
starting marker for an environment: \cs[no-index]{begin}, followed by a
begin-group token (|\cB.|), then any number of tokens which are
neither begin-group nor end-group character tokens (|\c[^BE].*|),
ending with an end-group token (|\cE.|). As explained later,
the parentheses \enquote{capture} the result of |\c[^BE].*|,
giving us access to the name of the environment when doing
replacements.

\section{Regular Expression Variables}

If a regular expression is to be used several times,
it is better to compile it once rather than doing it
each time the regular expression is used. The compiled
regular expression is stored in a variable. All
of this module's functions can be given their
regular expression argument either as an explicit string
or as a compiled regular expression.

\begin{variable}{\lTmpaRegex,\lTmpbRegex,\lTmpcRegex,\lTmpiRegex,\lTmpjRegex,\lTmpkRegex}
Scratch regex variables for local assignment. These are never used by
\verb!function! package, and so are safe for use with any function.
However, they may be overwritten by other non-kernel
code and so should only be used for short-term storage.
\end{variable}

\begin{variable}{\gTmpaRegex,\gTmpbRegex,\gTmpcRegex,\gTmpiRegex,\gTmpjRegex,\gTmpkRegex}
Scratch regex variables for global assignment. These are never used by
\verb!function! package, and so are safe for use with any function.
However, they may be overwritten by other non-kernel
code and so should only be used for short-term storage.
\end{variable}

\begin{function}{\regexNew}
\begin{syntax}
\cs{regexNew} \meta{regex var}
\end{syntax}
Creates a new \meta{regex var} or raises an error if the
name is already taken. The declaration is global. The
\meta{regex var} is initially such that it never matches.
\end{function}

\begin{function}{\regexSet}
\begin{syntax}
\cs{regexSet} \meta{regex var} \Arg{regex}
\end{syntax}
Stores a compiled version of the \meta{regular expression} in the
\meta{regex var}. For instance, this function can be
used as
\begin{codehigh}
\regexNew \lMyRegex
\regexSet \lMyRegex {my\ (simple\ )? reg(ex|ular\ expression)}
\end{codehigh}
\end{function}

\begin{function}{\regexConst}
\begin{syntax}
\cs{regexConst} \meta{regex var} \Arg{regex}
\end{syntax}
Creates a new constant \meta{regex var} or raises an error if the name
is already taken.  The value of the \meta{regex var} is set
globally to the compiled version of the \meta{regular expression}.
\end{function}

\begin{function}{\regexLog,\regexVarLog,\regexShow,\regexVarShow}
\begin{syntax}
\cs{regexLog} \Arg{regex}
\cs{regexVarLog} \meta{regex var}
\cs{regexShow} \Arg{regex}
\cs{regexVarShow} \meta{regex var}
\end{syntax}
Displays in the terminal or writes in the log file (respectively)
how \pkg{l3regex} interprets the \meta{regex}. For instance,
\cs{regexShow} \verb+{\A X|Y}+ shows
\begin{codehigh}
+-branch
  anchor at start (\A)
  char code 88 (X)
+-branch
  char code 89 (Y)
\end{codehigh}
indicating that the anchor |\A| only applies to the first branch:
the second branch is not anchored to the beginning of the match.
\end{function}

\section{Regular Expression Matching}

\begin{function}{\regexMatch,\regexMatchT,\regexMatchF,\regexMatchTF}
\begin{syntax}
\cs{regexMatch} \Arg{regex} \Arg{token list}
\cs{regexMatchT} \Arg{regex} \Arg{token list} \Arg{true code}
\cs{regexMatchF} \Arg{regex} \Arg{token list} \Arg{false code}
\cs{regexMatchTF} \Arg{regex} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{regular expression} matches any part
of the \meta{token list}. For instance,
\begin{demohigh}
\regexMatchTF {b [cde]*} {abecdcx} {\prgPrint{True}} {\prgPrint{False}}
\regexMatchTF {[b-dq-w]} {example} {\prgPrint{True}} {\prgPrint{False}}
\end{demohigh}
\end{function}

\begin{function}{\regexVarMatch,\regexVarMatchT,\regexVarMatchF,\regexVarMatchTF}
\begin{syntax}
\cs{regexVarMatch} \meta{regex var} \Arg{token list}
\cs{regexVarMatchT} \meta{regex var} \Arg{token list} \Arg{true code}
\cs{regexVarMatchF} \meta{regex var} \Arg{token list} \Arg{false code}
\cs{regexVarMatchTF} \meta{regex var} \Arg{token list} \Arg{true code} \Arg{false code}
\end{syntax}
Tests whether the \meta{regex var} matches any part of the \meta{token list}.
\end{function}

\begin{function}{\regexCount,\regexVarCount}
\begin{syntax}
\cs{regexCount} \Arg{regex} \Arg{token list} \meta{int var}
\cs{regexVarCount} \meta{regex var} \Arg{token list} \meta{int var}
\end{syntax}
Sets \meta{int var} within the current \TeX{} group level
equal to the number of times
\meta{regular expression} appears in \meta{token list}.
The search starts by finding the left-most longest match,
respecting greedy and lazy (non-greedy) operators. Then the search
starts again from the character following the last character
of the previous match, until reaching the end of the token list.
Infinite loops are prevented in the case where the regular expression
can match an empty token list: then we count one match between each
pair of characters. For instance,
\begin{demohigh}
\intNew \lFooInt
\regexCount {(b+|c)} {abbababcbb} \lFooInt
\intUse \lFooInt
\end{demohigh}
\end{function}

\begin{function}{\regexMatchCase}
\begin{syntax}
\cs{regexMatchCase}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{code case_n}
~ ~ |}| \Arg{token list}
\end{syntax}
Determines which of the \meta{regular expressions} matches at the earliest
point in the \meta{token list}, and leaves the corresponding \meta{code_i}.
If several \meta{regex} match starting at the same point,
then the first one in the list is selected and the others are discarded.
Each \meta{regex} can either be given as a regex variable or as an explicit
regular expression.
\par
In detail, for each starting position in the \meta{token list}, each
of the \meta{regex} is searched in turn.  If one of them matches
then the corresponding \meta{code} is used and everything else is
discarded, while if none of the \meta{regex} match at a given
position then the next starting position is attempted.  If none of
the \meta{regex} match anywhere in the \meta{token list} then
nothing is left in the input stream.  Note that this differs from
nested \cs{regexMatch} statements since all \meta{regex} are
attempted at each position rather than attempting to match
\meta{regex_1} at every position before moving on to \meta{regex_2}.
\end{function}

\begin{function}{\regexMatchCaseT}
\begin{syntax}
\cs{regexMatchCaseT}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{code case_n}
~ ~ |}| \Arg{token list}
~ ~ \Arg{true code}
\end{syntax}
Determines which of the \meta{regular expressions} matches at the
earliest point in the \meta{token list}, and leaves the
corresponding \meta{code_i} followed by the \meta{true code} in the
input stream. If several \meta{regex} match starting at the same
point, then the first one in the list is selected and the others are
discarded. Each \meta{regex} can either be given
as a regex variable or as an explicit regular expression.
\end{function}

\begin{function}{\regexMatchCaseF}
\begin{syntax}
\cs{regexMatchCaseF}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{code case_n}
~ ~ |}| \Arg{token list}
~ ~ \Arg{false code}
\end{syntax}
Determines which of the \meta{regular expressions} matches at the
earliest point in the \meta{token list}, and leaves the
corresponding \meta{code_i}.
If several \meta{regex} match starting at the same
point, then the first one in the list is selected and the others are
discarded.  If none of the \meta{regex} match, the \meta{false code}
is left in the input stream.  Each \meta{regex} can either be given
as a regex variable or as an explicit regular expression.
\end{function}

\begin{function}{\regexMatchCaseTF}
\begin{syntax}
\cs{regexMatchCaseTF}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{code case_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{code case_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{code case_n}
~ ~ |}| \Arg{token list}
~ ~ \Arg{true code} \Arg{false code}
\end{syntax}
Determines which of the \meta{regular expressions} matches at the
earliest point in the \meta{token list}, and leaves the
corresponding \meta{code_i} followed by the \meta{true code} in the
input stream.  If several \meta{regex} match starting at the same
point, then the first one in the list is selected and the others are
discarded.  If none of the \meta{regex} match, the \meta{false code}
is left in the input stream.  Each \meta{regex} can either be given
as a regex variable or as an explicit regular expression.
\end{function}

\section{Regular Expression Submatch Extraction}

\begin{function}{\regexExtractOnce,\regexExtractOnceT,\regexExtractOnceF,\regexExtractOnceTF}
\begin{syntax}
\cs{regexExtractOnce} \Arg{regex} \Arg{token list} \meta{seq var}
\cs{regexExtractOnceT} \Arg{regex} \Arg{token list} \meta{seq var} \Arg{true code}
\cs{regexExtractOnceF} \Arg{regex} \Arg{token list} \meta{seq var} \Arg{false code}
\cs{regexExtractOnceTF} \Arg{regex} \Arg{token list} \meta{seq var} \Arg{true code} \Arg{false code}
\end{syntax}
Finds the first match of the \meta{regular expression} in the
\meta{token list}. If it exists, the match is stored as the first
item of the \meta{seq var}, and further items are the contents of
capturing groups, in the order of their opening parenthesis. The
\meta{seq var} is assigned locally. If there is no match, the
\meta{seq var} is cleared.  The testing versions insert the
\meta{true code} into the input stream if a match was found, and the
\meta{false code} otherwise.
\par
For instance, assume that you type
\begin{codehigh}
\regexExtractOnce {\A(La)?TeX(!*)\Z} {LaTeX!!!} \lTmpaSeq
\end{codehigh}
Then the regular expression (anchored at the start with |\A| and
at the end with |\Z|) must match the whole token list. The first
capturing group, |(La)?|, matches |La|, and the second capturing
group, |(!*)|, matches |!!!|. Thus, \cs{lTmpaSeq} contains as a result
the items |{LaTeX!!!}|, |{La}|, and |{!!!}|.
Note that the $n$-th item of \cs{lTmpaSeq}, as obtained using
\cs{seqVarItem}, correspond to the submatch numbered $(n-1)$ in
functions such as \cs{regexReplaceOnce}.
\end{function}

\begin{function}{\regexVarExtractOnce,\regexVarExtractOnceT,\regexVarExtractOnceF,\regexVarExtractOnceTF}
\begin{syntax}
\cs{regexVarExtractOnce} \meta{regex var} \Arg{token list} \meta{seq var}
\cs{regexVarExtractOnceT} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{true code}
\cs{regexVarExtractOnceF} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{false code}
\cs{regexVarExtractOnceTF} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{true code} \Arg{false code}
\end{syntax}
Finds the first match of the \meta{regex var} in the
\meta{token list}. If it exists, the match is stored as the first
item of the \meta{seq var}, and further items are the contents of
capturing groups, in the order of their opening parenthesis. The
\meta{seq var} is assigned locally. If there is no match, the
\meta{seq var} is cleared.  The testing versions insert the
\meta{true code} into the input stream if a match was found, and the
\meta{false code} otherwise.
\end{function}

\begin{function}{\regexExtractAll,\regexExtractAllT,\regexExtractAllF,\regexExtractAllTF}
\begin{syntax}
\cs{regexExtractAll} \Arg{regex} \Arg{token list} \meta{seq var}
\cs{regexExtractAllT} \Arg{regex} \Arg{token list} \meta{seq var} \Arg{true code}
\cs{regexExtractAllF} \Arg{regex} \Arg{token list} \meta{seq var} \Arg{false code}
\cs{regexExtractAllTF} \Arg{regex} \Arg{token list} \meta{seq var} \Arg{true code} \Arg{false code}
\end{syntax}
Finds all matches of the \meta{regular expression}
in the \meta{token list}, and stores all the submatch information
in a single sequence (concatenating the results of
multiple \cs{regexExtractOnce} calls).
The \meta{seq var} is assigned locally. If there is no match,
the \meta{seq var} is cleared.
The testing versions insert the \meta{true code} into the input
stream if a match was found, and the \meta{false code} otherwise.
For instance, assume that you type
\begin{codehigh}
\regexExtractAll {\w+} {Hello, world!} \lTmpaSeq
\end{codehigh}
Then the regular expression matches twice, the resulting
sequence contains the two items |{Hello}| and |{world}|.
\end{function}

\begin{function}{\regexVarExtractAll,\regexVarExtractAllT,\regexVarExtractAllF,\regexVarExtractAllTF}
\begin{syntax}
\cs{regexVarExtractAll} \meta{regex var} \Arg{token list} \meta{seq var}
\cs{regexVarExtractAllT} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{true code}
\cs{regexVarExtractAllF} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{false code}
\cs{regexVarExtractAllTF} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{true code} \Arg{false code}
\end{syntax}
Finds all matches of the \meta{regex var}
in the \meta{token list}, and stores all the submatch information
in a single sequence (concatenating the results of
multiple \cs{regexVarExtractOnce} calls).
The \meta{seq var} is assigned locally. If there is no match,
the \meta{seq var} is cleared.
The testing versions insert the \meta{true code} into the input
stream if a match was found, and the \meta{false code} otherwise.
\end{function}

\begin{function}{\regexSplit,\regexSplitT,\regexSplitF,\regexSplitTF}
\begin{syntax}
\cs{regexSplit} \Arg{regular expression} \Arg{token list} \meta{seq var}
\cs{regexSplitT} \Arg{regular expression} \Arg{token list} \meta{seq var} \Arg{true code}
\cs{regexSplitF} \Arg{regular expression} \Arg{token list} \meta{seq var} \Arg{false code}
\cs{regexSplitTF} \Arg{regular expression} \Arg{token list} \meta{seq var} \Arg{true code} \Arg{false code}
\end{syntax}
Splits the \meta{token list} into a sequence of parts, delimited by
matches of the \meta{regular expression}. If the \meta{regular expression}
has capturing groups, then the token lists that they match are stored as
items of the sequence as well. The assignment to \meta{seq var} is local.
If no match is found the resulting \meta{seq var} has the
\meta{token list} as its sole item. If the \meta{regular expression}
matches the empty token list, then the \meta{token list} is split
into single tokens.
The testing versions insert the \meta{true code} into the input
stream if a match was found, and the \meta{false code} otherwise.
For example, after
\begin{codehigh}
\seqNew \lPathSeq
\regexSplit {/} {the/path/for/this/file.tex} \lPathSeq
\end{codehigh}
the sequence |\lPathSeq| contains the items |{the}|, |{path}|,
|{for}|, |{this}|, and |{file.tex}|.
\end{function}

\begin{function}{\regexVarSplit,\regexVarSplitT,\regexVarSplitF,\regexVarSplitTF}
\begin{syntax}
\cs{regexVarSplit} \meta{regex var} \Arg{token list} \meta{seq var}
\cs{regexVarSplitT} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{true code}
\cs{regexVarSplitF} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{false code}
\cs{regexVarSplitTF} \meta{regex var} \Arg{token list} \meta{seq var} \Arg{true code} \Arg{false code}
\end{syntax}
Splits the \meta{token list} into a sequence of parts, delimited by
matches of the \meta{regular expression}. If the \meta{regex var}
has capturing groups, then the token lists that they match are stored as
items of the sequence as well. The assignment to \meta{seq var} is local.
If no match is found the resulting \meta{seq var} has the
\meta{token list} as its sole item. If the \meta{regular expression}
matches the empty token list, then the \meta{token list} is split
into single tokens.
The testing versions insert the \meta{true code} into the input
stream if a match was found, and the \meta{false code} otherwise.
\end{function}

\section{Regular Expression Replacement}

\begin{function}{\regexReplaceOnce,\regexReplaceOnceT,\regexReplaceOnceT,\regexReplaceOnceTF}
\begin{syntax}
\cs{regexReplaceOnce} \Arg{regular expression} \Arg{replacement} \meta{tl var}
\cs{regexReplaceOnceT} \Arg{regular expression} \Arg{replacement} \meta{tl var} \Arg{true code}
\cs{regexReplaceOnceF} \Arg{regular expression} \Arg{replacement} \meta{tl var} \Arg{false code}
\cs{regexReplaceOnceTF} \Arg{regular expression} \Arg{replacement} \meta{tl var} \Arg{true code} \Arg{false code}
\end{syntax}
Searches for the \meta{regular expression} in the contents of the
\meta{tl var} and replaces the first match with the
\meta{replacement}. In the \meta{replacement},
|\0| represents the full match, |\1| represent the contents of the
first capturing group, |\2| of the second, \emph{etc.}
The result is assigned locally to \meta{tl var}.
\end{function}

\begin{function}{\regexReplaceOnce,\regexReplaceOnceT,\regexReplaceOnceT,\regexReplaceOnceTF}
\begin{syntax}
\cs{regexVarReplaceOnce} \meta{regex var} \Arg{replacement} \meta{tl var}
\cs{regexVarReplaceOnceT} \meta{regex var} \Arg{replacement} \meta{tl var} \Arg{true code}
\cs{regexVarReplaceOnceF} \meta{regex var} \Arg{replacement} \meta{tl var} \Arg{false code}
\cs{regexVarReplaceOnceTF} \meta{regex var} \Arg{replacement} \meta{tl var} \Arg{true code} \Arg{false code}
\end{syntax}
Searches for the \meta{regex var} in the contents of the
\meta{tl var} and replaces the first match with the
\meta{replacement}. In the \meta{replacement},
|\0| represents the full match, |\1| represent the contents of the
first capturing group, |\2| of the second, \emph{etc.}
The result is assigned locally to \meta{tl var}.
\end{function}

\begin{function}{\regexReplaceAll,\regexReplaceAllT,\regexReplaceAllF,\regexReplaceAllTF}
\begin{syntax}
\cs{regexReplaceAll} \Arg{regular expression} \Arg{replacement} \meta{tl var}
\cs{regexReplaceAllT} \Arg{regular expression} \Arg{replacement} \meta{tl var} \Arg{true code}
\cs{regexReplaceAllF} \Arg{regular expression} \Arg{replacement} \meta{tl var} \Arg{false code}
\cs{regexReplaceAllTF} \Arg{regular expression} \Arg{replacement} \meta{tl var} \Arg{true code} \Arg{false code}
\end{syntax}
Replaces all occurrences of the \meta{regex var} in the
contents of the \meta{tl var}
by the \meta{replacement}, where |\0| represents
the full match, |\1| represent the contents of the first capturing
group, |\2| of the second, \emph{etc.} Every match is treated
independently, and matches cannot overlap.  The result is assigned
locally to \meta{tl~var}.
\end{function}

\begin{function}{\regexVarReplaceAll,\regexVarReplaceAllT,\regexVarReplaceAllF,\regexVarReplaceAllTF}
\begin{syntax}
\cs{regexVarReplaceAll} \meta{regex var} \Arg{replacement} \meta{tl var}
\cs{regexVarReplaceAllT} \meta{regex var} \Arg{replacement} \meta{tl var} \Arg{true code}
\cs{regexVarReplaceAllF} \meta{regex var} \Arg{replacement} \meta{tl var} \Arg{false code}
\cs{regexVarReplaceAllTF} \meta{regex var} \Arg{replacement} \meta{tl var} \Arg{true code} \Arg{false code}
\end{syntax}
Replaces all occurrences of the \meta{regular expression} in the
contents of the \meta{tl var}
by the \meta{replacement}, where |\0| represents
the full match, |\1| represent the contents of the first capturing
group, |\2| of the second, \emph{etc.} Every match is treated
independently, and matches cannot overlap.  The result is assigned
locally to \meta{tl var}.
\end{function}

\begin{function}{\regexReplaceCaseOnce}
\begin{syntax}
\cs{regexReplaceCaseOnce}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
\end{syntax}
Replaces the earliest match of the regular expression
"(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the \meta{token list variable}
by the \meta{replacement} corresponding to which \meta{regex_i} matched.
If none of the \meta{regex} match, then the
\meta{tl var} is not modified. Each \meta{regex} can either be given as a regex
variable or as an explicit regular expression.
\par
In detail, for each starting position in the \meta{token list}, each
of the \meta{regex} is searched in turn.  If one of them matches
then it is replaced by the corresponding \meta{replacement} as
described for \cs{regexReplaceOnce}.  This is equivalent to
checking with \cs{regexMatchCase} which \meta{regex} matches,
then performing the replacement with \cs{regexReplaceOnce}.
\end{function}

\begin{function}{\regexReplaceCaseOnceT}
\begin{syntax}
\cs{regexReplaceCaseOnceT}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
~ ~ \Arg{true code}
\end{syntax}
Replaces the earliest match of the regular expression
"(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the \meta{token list variable}
by the \meta{replacement} corresponding to which
\meta{regex_i} matched, then leaves the \meta{true code} in the
input stream. If none of the \meta{regex} match, then the
\meta{tl var} is not modified. Each \meta{regex} can either be given as a regex
variable or as an explicit regular expression.
\end{function}

\begin{function}{\regexReplaceCaseOnceF}
\begin{syntax}
\cs{regexReplaceCaseOnceF}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
~ ~ \Arg{false code}
\end{syntax}
Replaces the earliest match of the regular expression
"(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the \meta{token list variable}
by the \meta{replacement} corresponding to which
\meta{regex_i} matched. If none of the \meta{regex} match, then the
\meta{tl var} is not modified, and the \meta{false code} is left in
the input stream.  Each \meta{regex} can either be given as a regex
variable or as an explicit regular expression.
\end{function}

\begin{function}{\regexReplaceCaseOnceTF}
\begin{syntax}
\cs{regexReplaceCaseOnceTF}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
~ ~ \Arg{true code} \Arg{false code}
\end{syntax}
Replaces the earliest match of the regular expression
"(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the \meta{token list variable}
by the \meta{replacement} corresponding to which
\meta{regex_i} matched, then leaves the \meta{true code} in the
input stream.  If none of the \meta{regex} match, then the
\meta{tl var} is not modified, and the \meta{false code} is left in
the input stream.  Each \meta{regex} can either be given as a regex
variable or as an explicit regular expression.
\end{function}

\begin{function}{\regexReplaceCaseAll}
\begin{syntax}
\cs{regexReplaceCaseAll}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
\end{syntax}
Replaces all occurrences of all \meta{regex} in the \meta{token~list}
by the corresponding \meta{replacement}. Every match is
treated independently, and matches cannot overlap. The result is
assigned locally to \meta{tl var}.
\par
In detail, for each starting position in the \meta{token list}, each
of the \meta{regex} is searched in turn.  If one of them matches
then it is replaced by the corresponding \meta{replacement}, and the
search resumes at the position that follows this match (and
replacement).  For instance
%% FIXME
%\begin{codehigh}
%\tlSet \lTmpaTl {Hello, world!}
%\regexReplaceCaseAll
%  {
%    {[A-Za-z]+} {``\0''}
%    {\b}        {---}
%    {.}         {[\0]}
%  } \lTmpaTl
%\end{codehigh}
\begin{codehigh}
\tlSet \lTmpaTl {Hello, world!}
\regexReplaceCaseAll
  {
    {[A-Za-z]+} {``\0''}
    {\b} {---}
    {.} {[\0]}
  } \lTmpaTl
\end{codehigh}
results in \cs{lTmpaTl} having the contents
\verb*|``Hello''---[,][ ]``world''---[!]|.  Note in particular that
the word-boundary assertion |\b| did not match at the start of words
because the case |[A-Za-z]+| matched at these positions.  To change
this, one could simply swap the order of the two cases in the
argument of \cs{regexReplaceCaseAll}.
\end{function}

\begin{function}{\regexReplaceCaseAllT}
\begin{syntax}
\cs{regexReplaceCaseAllT}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
~ ~ \Arg{true code}
\end{syntax}
Replaces all occurrences of all \meta{regex} in the \meta{token~list}
by the corresponding \meta{replacement}.  Every match is
treated independently, and matches cannot overlap. The result is
assigned locally to \meta{tl var}, and the \meta{true code}
is left in the input stream if any replacement was made.
\end{function}

\begin{function}{\regexReplaceCaseAllF}
\begin{syntax}
\cs{regexReplaceCaseAllF}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
~ ~ \Arg{false code}
\end{syntax}
Replaces all occurrences of all \meta{regex} in the \meta{token~list}
by the corresponding \meta{replacement}.  Every match is
treated independently, and matches cannot overlap. The result is
assigned locally to \meta{tl var}, and the \meta{false code} is left
in the input stream if not any replacement was made.
\end{function}

\begin{function}{\regexReplaceCaseAllTF}
\begin{syntax}
\cs{regexReplaceCaseAllTF}
~ ~ |{|
~ ~ ~ ~ \Arg{regex_1} \Arg{replacement_1}
~ ~ ~ ~ \Arg{regex_2} \Arg{replacement_2}
~ ~ ~ ~ \ldots
~ ~ ~ ~ \Arg{regex_n} \Arg{replacement_n}
~ ~ |}| \meta{tl var}
~ ~ \Arg{true code} \Arg{false code}
\end{syntax}
Replaces all occurrences of all \meta{regex} in the \meta{token
list} by the corresponding \meta{replacement}.  Every match is
treated independently, and matches cannot overlap.  The result is
assigned locally to \meta{tl var}, and the \meta{true code} or
\meta{false code} is left in the input stream depending on whether
any replacement was made or not.
\end{function}

\section{Syntax of Regular Expressions}

\subsection{Regular Expression Examples}

We start with a few examples, and encourage the reader to apply
\cs{regexShow} to these regular expressions.
\begin{itemize}
\item |Cat| matches the word \enquote{Cat} capitalized in this way,
  but also matches the beginning of the word \enquote{Cattle}: use
  |\bCat\b| to match a complete word only.
\item |[abc]| matches one letter among \enquote{a}, \enquote{b},
  \enquote{c}; the pattern \verb"(a|b|c)" matches the same three
  possible letters (but see the discussion of submatches below).
\item |[A-Za-z]*| matches any number (due to the quantifier
  \verb"*") of Latin letters (not accented).
\item |\c{[A-Za-z]*}| matches a control sequence made of Latin
  letters.
\item |\_[^\_]*\_| matches an underscore, any number of characters
  other than underscore, and another underscore; it is equivalent to
  |\_.*?\_| where |.| matches arbitrary characters and the
  lazy quantifier |*?| means to match as few characters as
  possible, thus avoiding matching underscores.
\item |[\+\-]?\d+| matches an explicit integer with at most one
  sign.
\item \verb*"[\+\-\ ]*\d+\ *" matches an explicit integer with any
  number of $+$ and $-$ signs, with spaces allowed except within the
  mantissa, and surrounded by spaces.
\item \verb*"[\+\-\ ]*(\d+|\d*\.\d+)\ *" matches an explicit integer or
  decimal number; using \verb*"[.,]" instead of \verb*"\." would allow
  the comma as a decimal marker.
\item
  \verb*"[\+\-\ ]*(\d+|\d*\.\d+)\ *((?i)pt|in|[cem]m|ex|[bs]p|[dn]d|[pcn]c)\ *"
  \allowbreak matches an explicit dimension with any unit that \TeX{} knows, where
  \verb*"(?i)" means to treat lowercase and uppercase letters
  identically.
\item \verb*"[\+\-\ ]*((?i)nan|inf|(\d+|\d*\.\d+)(\ *e[\+\-\ ]*\d+)?)\ *"
  matches an explicit floating point number or the special values
  \verb*"nan" and \verb*"inf" (with signs and spaces allowed).
\item \verb*"[\+\-\ ]*(\d+|\cC.)\ *" matches an explicit integer or
  control sequence (without checking whether it is an integer
  variable).
\item |\G.*?\K| at the beginning of a regular expression matches and
  discards (due to |\K|) everything between the end of the previous
  match (|\G|) and what is matched by the rest of the regular
  expression; this is useful in \cs{regexReplaceAll} when the
  goal is to extract matches or submatches in a finer way than with
  \cs{regexExtractAll}.
\end{itemize}
While it is impossible for a regular expression to match only integer
expressions, \newline\verb*"[\+\-\(]*\d+\)*([\+\-*/][\+\-\(]*\d+\)*)*" matches among
other things all valid integer expressions (made only with explicit
integers).  One should follow it with further testing.

\subsection{Characters in Regular Expressions}

Most characters match exactly themselves,
with an arbitrary category code. Some characters are
special and must be escaped with a backslash (\emph{e.g.}, |\*|
matches a star character). Some escape sequences of
the form backslash--letter also have a special meaning
(for instance |\d| matches any digit). As a rule,
\begin{itemize}
\item every alphanumeric character (\texttt{A}--\texttt{Z},
  \texttt{a}--\texttt{z}, \texttt{0}--\texttt{9}) matches
  exactly itself, and should not be escaped, because
  |\A|, |\B|, \ldots{} have special meanings;
\item non-alphanumeric printable ASCII characters can (and should)
  always be escaped: many of them have special meanings (\emph{e.g.},
  use |\(|, |\)|, |\?|, |\.|, |\^|);
\item spaces should always be escaped (even in character
  classes);
\item any other character may be escaped or not, without any
  effect: both versions match exactly that character.
\end{itemize}
Note that these rules play nicely with the fact that many
non-alphanumeric characters are difficult to input into \TeX{}
under normal category codes. For instance, |\\abc\%|
matches the characters |\abc%| (with arbitrary category codes),
but does not match the control sequence |\abc| followed by a
percent character. Matching control sequences can be done
using the |\c|\Arg{regex} syntax (see below).

Any special character which appears at a place where its special
behaviour cannot apply matches itself instead (for instance, a
quantifier appearing at the beginning of a string), after raising a
warning.

Characters.
\begin{l3regex-syntax}
  \item[\\x\{hh\ldots{}\}] Character with hex code \texttt{hh\ldots{}}
  \item[\\xhh] Character with hex code \texttt{hh}.
  \item[\\a] Alarm (hex 07).
  \item[\\e] Escape (hex 1B).
  \item[\\f] Form-feed (hex 0C).
  \item[\\n] New line (hex 0A).
  \item[\\r] Carriage return (hex 0D).
  \item[\\t] Horizontal tab (hex 09).
\end{l3regex-syntax}

\subsection{Characters Classes}

Character types.
\begin{l3regex-syntax}
  \item[.] A single period matches any token.
  \item[\\d] Any decimal digit.
  \item[\\h] Any horizontal space character,
    equivalent to |[\ \^^I]|: space and tab.
  \item[\\s] Any space character,
    equivalent to |[\ \^^I\^^J\^^L\^^M]|.
  \item[\\v] Any vertical space character,
    equivalent to |[\^^J\^^K\^^L\^^M]|. Note that |\^^K| is a vertical space,
    but not a space, for compatibility with Perl.
  \item[\\w] Any word character, \emph{i.e.},
    alphanumerics and underscore, equivalent to the explicit
    class |[A-Za-z0-9\_]|.
  \item[\\D] Any token not matched by |\d|.
  \item[\\H] Any token not matched by |\h|.
  \item[\\N] Any token other than the |\n| character (hex 0A).
  \item[\\S] Any token not matched by |\s|.
  \item[\\V] Any token not matched by |\v|.
  \item[\\W] Any token not matched by |\w|.
\end{l3regex-syntax}
Of those, |.|, |\D|, |\H|, |\N|, |\S|, |\V|, and |\W| match arbitrary
control sequences.

Character classes match exactly one token in the subject.
\begin{l3regex-syntax}
  \item[{[\ldots{}]}] Positive character class.
    Matches any of the specified tokens.
  \item[{[\char`\^\ldots{}]}] Negative character class.
    Matches any token other than the specified characters.
  \item[{x-y}] Within a character class, this denotes a range (can be
    used with escaped characters).
  \item[{[:\meta{name}:]}] Within a character class (one more set of
    brackets), this denotes the \textsc{posix} character class
    \meta{name}, which can be \texttt{alnum}, \texttt{alpha},
    \texttt{ascii}, \texttt{blank}, \texttt{cntrl}, \texttt{digit},
    \texttt{graph}, \texttt{lower}, \texttt{print}, \texttt{punct},
    \texttt{space}, \texttt{upper}, \texttt{word}, or \texttt{xdigit}.
  \item[{[:\char`\^\meta{name}:]}] Negative \textsc{posix} character class.
\end{l3regex-syntax}
For instance, |[a-oq-z\cC.]| matches any lowercase latin letter
except |p|, as well as control sequences (see below for a description
of |\c|).

In character classes, only |[|, |^|, |-|, |]|, |\| and spaces are
special, and should be escaped. Other non-alphanumeric characters can
still be escaped without harm. Any escape sequence which matches a
single character (|\d|, |\D|, \emph{etc.}) is supported in character
classes.  If the first character is |^|, then
the meaning of the character class is inverted; |^| appearing anywhere
else in the range is not special.  If the first character (possibly
following a leading |^|) is |]| then it does not need to be escaped
since ending the range there would make it empty.
Ranges of characters
can be expressed using |-|, for instance, |[\D 0-5]| and |[^6-9]| are
equivalent.

\subsection{Structure: Alternatives, Groups, Repetitions}

Quantifiers (repetition).
\begin{l3regex-syntax}
  \item[?] $0$ or $1$, greedy.
  \item[??] $0$ or $1$, lazy.
  \item[*] $0$ or more, greedy.
  \item[*?] $0$ or more, lazy.
  \item[+] $1$ or more, greedy.
  \item[+?] $1$ or more, lazy.
  \item[\{$n$\}] Exactly $n$.
  \item[\{$n,$\}] $n$ or more, greedy.
  \item[\{$n,$\}?] $n$ or more, lazy.
  \item[\{$n,m$\}] At least $n$, no more than $m$, greedy.
  \item[\{$n,m$\}?] At least $n$, no more than $m$, lazy.
\end{l3regex-syntax}
For greedy quantifiers the regex code will first investigate matches
that involve as many repetitions as possible, while for lazy
quantifiers it investigates matches with as few repetitions as
possible first.

Alternation and capturing groups.
\begin{l3regex-syntax}
  \item[A\char`|B\char`|C] Either one of \texttt{A}, \texttt{B},
    or \texttt{C}, investigating \texttt{A} first.
  \item[(\ldots{})] Capturing group.
  \item[(?:\ldots{})] Non-capturing group.
  \item[(?\char`|\ldots{})] Non-capturing group which resets
    the group number for capturing groups in each alternative.
    The following group is numbered with the first unused
    group number.
\end{l3regex-syntax}

Capturing groups are a means of extracting information about the
match. Parenthesized groups are labelled in the order of their
opening parenthesis, starting at $1$. The contents of those groups
corresponding to the \enquote{best} match (leftmost longest)
can be extracted and stored in a sequence of token lists using for
instance \cs{regexExtractOnceTF}.

The |\K| escape sequence resets the beginning of the match to the
current position in the token list. This only affects what is reported
as the full match. For instance,
\begin{codehigh}
\regexExtractAll {a \K .} {a123aaxyz} \lFooSeq
\end{codehigh}
results in \cs{lFooSeq} containing the items |{1}| and |{a}|: the
true matches are |{a1}| and |{aa}|, but they are trimmed by the use of
|\K|. The |\K| command does not affect capturing groups: for instance,
\begin{codehigh}
\regexExtractOnce {(. \K c)+ \d} {acbc3} \lFooSeq
\end{codehigh}
results in \cs{lFooSeq} containing the items |{c3}| and |{bc}|: the
true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets
the beginning of the match to the last position where it appears.

\subsection{Matching Exact Tokens}

The |\c| escape sequence allows to test the category code of tokens,
and match control sequences. Each character category is represented
by a single uppercase letter:
\begin{itemize}
\item |C| for control sequences;
\item |B| for begin-group tokens;
\item |E| for end-group tokens;
\item |M| for math shift;
\item |T| for alignment tab tokens;
\item |P| for macro parameter tokens;
\item |U| for superscript tokens (up);
\item |D| for subscript tokens (down);
\item |S| for spaces;
\item |L| for letters;
\item |O| for others; and
\item |A| for active characters.
\end{itemize}
The |\c| escape sequence is used as follows.
\begin{l3regex-syntax}
  \item[\\c\Arg{regex}] A control sequence whose csname matches the
    \meta{regex}, anchored at the beginning and end, so that |\c{begin}|
    matches exactly \cs[no-index]{begin}, and nothing else.
  \item[\\cX] Applies to the next object, which can be a character,
    escape character sequence such as |\x{0A}|, character class, or
    group, and forces this object to only match tokens with category
    |X| (any of |CBEMTPUDSLOA|. For instance, |\cL[A-Z\d]| matches
    uppercase letters and digits of category code letter, |\cC.|
    matches any control sequence, and |\cO(abc)| matches |abc| where
    each character has category other.\footnote{This last example also
    captures \enquote{\texttt{abc}} as a regex group; to avoid this
    use a non-capturing group \texttt{\textbackslash cO(?:abc)}.}
  \item[{\\c[XYZ]}] Applies to the next object, and forces it to only
    match tokens with category |X|, |Y|, or |Z| (each being any of
    |CBEMTPUDSLOA|). For instance, |\c[LSO](..)| matches two tokens of
    category letter, space, or other.
  \item[{\\c[\char`\^XYZ]}] Applies to the next object and prevents it
    from matching any token with category |X|, |Y|, or |Z| (each being
    any of |CBEMTPUDSLOA|). For instance, |\c[^O]\d| matches digits
    which have any category different from other.
\end{l3regex-syntax}
The category code tests can be used inside classes; for instance,
|[\cO\d \c[LO][A-F]]| matches what \TeX{} considers as hexadecimal
digits, namely digits with category other, or uppercase letters from
|A| to |F| with category either letter or other. Within a group
affected by a category code test, the outer test can be overridden by
a nested test: for instance, |\cL(ab\cO\*cd)| matches |ab*cd| where
all characters are of category letter, except |*| which has category
other.

The |\u| escape sequence allows to insert the contents of a token list
directly into a regular expression or a replacement, avoiding the need
to escape special characters. Namely, |\u|\Arg{var name} matches
the exact contents (both character codes and category codes) of the
variable \cs[no-index]{\meta{var name}}. %,
%which are obtained by applying \cs{exp_not:v} \Arg{var name} at the
%time the regular expression is compiled.
Within a |\c{...}|
control sequence matching, the |\u| escape sequence only expands its
argument once. %, in effect performing \cs{tl_to_str:v}.
Quantifiers are supported.

The |\ur| escape sequence allows to insert the contents of a |regex|
variable into a larger regular expression.  For instance,
|A\ur{lTmpaRegex}D| matches the tokens |A| and |D| separated by
something that matches the regular expression
\cs{lTmpaRegex}.  This behaves as if a non-capturing group
were surrounding \cs{lTmpaRegex}, and any group contained
in \cs{lTmpaRegex} is converted to a non-capturing group.
Quantifiers are supported.

For instance, if \cs{lTmpaRegex} has value \verb"B|C",
then |A\ur{l_tmpa_regex}D| is equivalent to \verb"A(?:B|C)D" (matching
|ABD| or |ACD|) and not to \verb"AB|CD" (matching |AB| or |CD|).  To
get the latter effect, it is simplest to use \TeX{}'s expansion
machinery directly: if \cs{lTmpaTl} contains
\verb"B|C" then the following two lines show the same result:
\begin{codehigh}
\regexShow {A \u{lTmpaTl} D}
\regexShow {A B | C D}
\end{codehigh}

\subsection{Miscellaneous}

Anchors and simple assertions.
\begin{l3regex-syntax}
  \item[\\b] Word boundary: either the previous token is matched by
    |\w| and the next by |\W|, or the opposite. For this purpose,
    the ends of the token list are considered as |\W|.
  \item[\\B] Not a word boundary: between two |\w| tokens
    or two |\W| tokens (including the boundary).
  \item[\char`^ \textrm{or} \\A]
    Start of the subject token list.
  \item[\char`$\textrm{,} \\Z \textrm{or} \\z] %^^A $
    End of the subject token list.
  \item[\\G] Start of the current match. This is only different from |^|
    in the case of multiple matches: for instance
    |\regexCount {\G a} {aaba} \lTmpaInt| yields $2$, but
    replacing |\G| by |^| would result in \cs{lTmpaInt} holding the
    value $1$.
\end{l3regex-syntax}

The option |(?i)| makes the match case insensitive (identifying
\texttt{A}--\texttt{Z} with \texttt{a}--\texttt{z}; no Unicode support
yet). This applies until the end of the group in which it appears, and
can be reverted using |(?-i)|. For instance, in
\verb"(?i)(a(?-i)b|c)d", the letters |a| and |d| are affected by the
|i| option. Characters within ranges and classes are affected
individually: |(?i)[Y-\\]| is equivalent to |[YZ\[\\yz]|, and
|(?i)[^aeiou]| matches any character which is not a vowel. Neither
character properties, nor |\c{...}| nor |\u{...}| are affected by the
|i| option.
%^^A \]

\section{Syntax of the Replacement Text}

Most of the features described in regular expressions do not make
sense within the replacement text.  Backslash introduces various
special constructions, described further below:
\begin{itemize}
  \item |\0| is the whole match;
  \item |\1| is the submatch that was matched by the first (capturing)
    group |(...)|; similarly for |\2|, \ldots{}, |\9| and
    |\g{|\meta{number}|}|;
  \item \verb*|\ | inserts a space (spaces are ignored when not
    escaped);
  \item |\a|, |\e|, |\f|, |\n|, |\r|, |\t|, |\xhh|, |\x{hhh}|
    correspond to single characters as in regular expressions;
  \item |\c|\Arg{cs name} inserts a control sequence;
  \item |\c|\meta{category}\meta{character} (see below);
  \item |\u|\Arg{tl var name} inserts the contents of the
    \meta{tl var} (see below).
\end{itemize}
Characters other than backslash and space are simply inserted in the
result (but since the replacement text is first converted to a string,
one should also escape characters that are special for \TeX{}, for
instance use |\#|).  Non-alphanumeric characters can always be safely
escaped with a backslash.

For instance,
\begin{demohigh}
\tlSet \lTmpaTl {Hello, world!}
\regexReplaceAll {([er]?l|o) .} {(\0--\1)} \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}

The submatches are numbered according to the order in which the
opening parenthesis of capturing groups appear in the regular
expression to match.  The $n$-th submatch is empty if there are fewer
than $n$ capturing groups or for capturing groups that appear in
alternatives that were not used for the match.  In case a capturing
group matches several times during a match (due to quantifiers) only
the last match is used in the replacement text. Submatches always keep
the same category codes as in the original token list.

By default, the category code of characters inserted by the
replacement are determined by the prevailing category code regime at
the time where the replacement is made, with two exceptions:
\begin{itemize}
\item space characters (with character code $32$) inserted with
  \verb*|\ | or |\x20| or |\x{20}| have category code $10$ regardless
  of the prevailing category code regime;
\item if the category code would be $0$ (escape), $5$ (newline),
  $9$ (ignore), $14$ (comment) or $15$ (invalid), it is replaced by
  $12$ (other) instead.
\end{itemize}
The escape sequence |\c| allows to insert characters
with arbitrary category codes, as well as control sequences.
\begin{l3regex-syntax}
\item[\\cX(\ldots{})] Produces the characters \enquote{\ldots{}} with
  category |X|, which must be one of |CBEMTPUDSLOA| as in regular
  expressions.  Parentheses are optional for a single character (which
  can be an escape sequence).  When nested, the innermost category
  code applies, for instance |\cL(Hello\cS\ world)!| gives this text
  with standard category codes.
\item[\\c\Arg{text}] Produces the control sequence with csname
  \meta{text}.  The \meta{text} may contain references to the
  submatches |\0|, |\1|, and so on, as in the example for |\u| below.
\end{l3regex-syntax}

The escape sequence |\u|\Arg{var name} allows to insert the
contents of the variable with name \meta{var name} directly into
the replacement, giving an easier control of category codes.  When
nested in |\c{|\ldots{}|}| and |\u{|\ldots{}|}| constructions, the
|\u| and |\c| escape sequences %perform \cs{tl_to_str:v}, namely
extract the value of the control sequence and turn it into a string.
Matches can also be used within the arguments of |\c| and |\u|.  For
instance,
\begin{demohigh}
\tlSet \lMyOneTl {first}
\tlSet \lMyTwoTl {\underline{second}}
\tlSet \lTmpaTl {One,Two,One,One}
\regexReplaceAll {[^,]+} {\u{lMy\0Tl}} \lTmpaTl
\tlUse \lTmpaTl
\end{demohigh}

Regex replacement is also a convenient way to produce token lists
with arbitrary category codes.  For instance
\begin{codehigh}
\tlClear \lTmpaTl
\regexReplaceAll { } {\cU\% \cA\~} \lTmpaTl
\end{codehigh}
results in \cs{lTmpaTl} containing the percent character
with category code $7$ (superscript) and an active tilde character.

\chapter{Token Manipulation (\texttt{Token})}

\begin{function}{\charLowercase,\charUppercase,\charTitlecase,\charFoldcase}
\begin{syntax}
\cs{charLowercase} \meta{char}
\cs{charUppercase} \meta{char}
\cs{charTitlecase} \meta{char}
\cs{charFoldcase} \meta{char}
\end{syntax}
Converts the \meta{char} to the equivalent case-changed character
as detailed by the function name (see %\cs{strFoldcase} and
\cs{textTitlecase} for details of these terms). The case mapping
is carried out with no context-dependence (\emph{cf.} \cs{textUppercase},
\emph{etc.}) These functions generate characters with the category code
of the \meta{char} (i.e. only the character code changes).
\end{function}

\begin{function}{\charStrLowercase,\charStrUppercase,\charStrTitlecase,\charStrFoldcase}
\begin{syntax}
\cs{charStrLowercase} \meta{char}
\cs{charStrUppercase} \meta{char}
\cs{charStrTitlecase} \meta{char}
\cs{charStrFoldcase} \meta{char}
\end{syntax}
Converts the \meta{char} to the equivalent case-changed character
as detailed by the function name (see %\cs{strFoldcase} and
\cs{textTitlecase} for details of these terms). The case mapping
is carried out with no context-dependence (\emph{cf.} \cs{textUppercase},
\emph{etc.}) These functions generate \enquote{other} (category code $12$)
characters.
\end{function}

\begin{function}{\charSetLccode}
\begin{syntax}
\cs{charSetLccode} \Arg{intexpr_1} \Arg{intexpr_2}
\end{syntax}
Sets up the behaviour of the \meta{character} when
found inside \cs{textLowercase}, such that \meta{character_1}
will be converted into \meta{character_2}. The two \meta{characters}
may be specified using an \meta{integer expression} for the character code
concerned. This may include the \TeX{} \verb|`|\meta{character}
method for converting a single character into its character code:
\begin{codehigh}
\charSetLccode {`\A} {`\a} % Standard behaviour
\charSetLccode {`\A} {`\A + 32}
\charSetLccode {65} {97}
\end{codehigh}
The setting applies within the current \TeX{} group.
\end{function}

\begin{function}{\charSetUccode}
\begin{syntax}
\cs{charSetUccode} \Arg{intexpr_1} \Arg{intexpr_2}
\end{syntax}
Sets up the behaviour of the \meta{character} when
found inside \cs{textUppercase}, such that \meta{character_1}
will be converted into \meta{character_2}. The two \meta{characters}
may be specified using an \meta{integer expression} for the character code
concerned. This may include the \TeX{} \verb|`|\meta{character}
method for converting a single character into its character code:
\begin{codehigh}
\charSetUccode {`\a} {`\A} % Standard behaviour
\charSetUccode {`\a} {`\a - 32}
\charSetUccode {97} {65}
\end{codehigh}
The setting applies within the current \TeX{} group.
\end{function}

\begin{function}{\charValueLccode}
\begin{syntax}
\cs{charValueLccode} \Arg{integer expression}
\end{syntax}
Returns the current lower case code of the \meta{character} with
character code given by the
\meta{integer expression}.
\end{function}

\begin{function}{\charValueUccode}
\begin{syntax}
\cs{charValueUccode} \Arg{integer expression}
\end{syntax}
Returns the current upper case code of the \meta{character} with
character code given by the
\meta{integer expression}.
\end{function}

%\begin{function}{\charShowValueLccode}
%\begin{syntax}
%\cs{charShowValueLccode} \Arg{integer expression}
%\end{syntax}
%Displays the current lower case code of the \meta{character} with
%character code given by the \meta{integer expression} on the
%terminal.
%\end{function}
%
%\begin{function}{\charShowValueUccode}
%\begin{syntax}
%\cs{charShowValueUccode} \Arg{integer expression}
%\end{syntax}
%Displays the current upper case code of the \meta{character} with
%character code given by the \meta{integer expression} on the
%terminal.
%\end{function}

\chapter{Text Processing (\texttt{Text})}

This module deals with manipulation of (formatted) text; such material is
comprised of a restricted set of token list content. The functions provided
here concern conversion of textual content for example in case changing,
%generation of bookmarks and extraction to tags.
Begin-group and end-group tokens in the \meta{text}
are normalized and become \verb|{| and \verb|}|, respectively.

\section{Case Changing}

These case changing functions are designed to work with Unicode input only.
As such, UTF-8 input is assumed for \emph{all} engines.
When used with XeTeX or LuaTeX a full range of Unicode transformations
are enabled. Specifically, the standard mappings
here follow those defined by the \href{http://www.unicode.org}
{Unicode Consortium} in \texttt{UnicodeData.txt} and
\texttt{SpecialCasing.txt}. In the case of $8$-bit engines, mappings
are provided for characters which can be represented in output typeset
using the \verb|T1|, \verb|T2| and \verb|LGR| font encodings.
Thus for example \texttt{ä} can be
case-changed using pdfTeX.  For pTeX only the ASCII range is
covered as the engine treats input outside of this range as east Asian.

%Importantly, notice that these functions are intended for working with
%user \emph{text for typesetting}. For case changing programmatic data see
%the \pkg{Str} module and discussion there of \cs{strLowercase},
%\cs{strUppercase} and \cs{strFoldcase}.

\begin{function}{\textExpand}
\begin{syntax}
\cs{textExpand} \Arg{text}
\end{syntax}
Takes user input \meta{text} and expands the content.
Protected commands (typically formatting) are left in place,
and no processing takes place of math mode material.
%(as delimited by pairs given in \cs{l_text_math_delims_tl}
%or as the argument to commands listed in \cs{l_text_math_arg_tl}).
Commands which are neither engine- nor \LaTeX{} protected are expanded exhaustively.
%Any commands listed in \cs{l_text_expand_exclude_tl},
%\cs{l_text_accents_tl} and \cs{l_text_letterlike_tl} are excluded from expansion.
\end{function}

\begin{function}{\textLowercase,\textUppercase,\textTitlecase,\textTitlecaseFirst}
\begin{syntax}
\cs{textLowercase}  \Arg{tokens}
\cs{textUppercase}  \Arg{tokens}
\cs{textTitlecase}  \Arg{tokens}
\cs{textTitlecaseFirst}  \Arg{tokens}
\end{syntax}
Takes user input \meta{text} first applies \cs{textExpand}, then
transforms the case of character tokens as specified by the
function name. The category code of letters are not changed by this
process (at least where they can be represented by the engine as a single
token: $8$-bit engines may require active characters).
\par
Upper- and lowercase have the obvious meanings. Titlecasing may be regarded
informally as converting the first character of the \meta{tokens} to
uppercase and the rest to lowercase. However, the process is more complex
than this as there are some situations where a single lowercase character
maps to a special form, for example \texttt{ij} in Dutch which becomes
\texttt{IJ}.
\par
For titlecasing, note that there are two functions available. The
function \cs{textTitlecase} applies (broadly) uppercasing to the first
letter of the input, then lowercasing to the remainder. In contrast,
\cs{textTitlecaseFirst} \emph{only} carries out the uppercasing operation,
and leaves the balance of the input unchanged.
%Determining whether non-letter characters at the start of text should switch
%from upper- to lowercasing is controllable.
%When \cs{l_text_titlecase_check_letter_bool} is \texttt{true},
%characters which are not letters (category code $11$) are
%left unchanged and \enquote{skipped}: the first \emph{letter} is uppercased.
%(With $8$-bit engines, this is extended to active characters which form
%part of a multi-byte letter codepoint.) When
%\cs{l_text_titlecase_check_letter_bool} is \texttt{false}, the first
%character is uppercased, and the rest lowercased, irrespective of the nature
%of the character.
\par
Case changing does not take place within math mode material. For example:
\begin{demohigh}
\textUppercase {Text $y=mx+c$ with {Braces}}
\end{demohigh}
\begin{demohigh}
\textLowercase {Text $Y=mX+c$ with {Braces}}
\end{demohigh}
%The arguments of commands listed in \cs{l_text_case_exclude_arg_tl}
%are excluded from case changing; the latter are entirely non-textual
%content (such as labels).
\end{function}

\begin{function}{\textLangLowercase,\textLangUppercase,\textLangTitlecase,\textLangTitlecaseFirst}
\begin{syntax}
\cs{textLangLowercase} \Arg{language} \Arg{tokens}
\cs{textLangUppercase} \Arg{language} \Arg{tokens}
\cs{textLangTitlecase} \Arg{language} \Arg{tokens}
\cs{textLangTitlecaseFirst} \Arg{language} \Arg{tokens}
\end{syntax}
Takes user input \meta{text} first applies \cs{textExpand}, then
transforms the case of character tokens as specified by the
function name. The category code of letters are not changed by this
process (at least where they can be represented by the engine as a single
token: $8$-bit engines may require active characters).
\par
These conversions are language-sensitive, and follow Unicode Consortium guidelines.
Currently, the languages recognised for special handling are as follows.
\begin{itemize}
\item Azeri and Turkish (\texttt{az} and \texttt{tr}).
  The case pairs I/i-dotless and I-dot/i are activated for these
  languages. The combining dot mark is removed when lowercasing
  I-dot and introduced when upper casing i-dotless.
\item German (\texttt{de-alt}).
  An alternative mapping for German in which the lowercase
  \emph{Eszett} maps to a \emph{gro\ss{}es Eszett}. Since there is
  a \verb|T1| slot for the \emph{gro\ss{}es Eszett} in \verb|T1|, this
  tailoring \emph{is} available with pdfTeX as well as in the
  Unicode \TeX{} engines.
\item Greek (\texttt{el}).
  Removes accents from Greek letters when uppercasing; titlecasing
  leaves accents in place. (At present this is implemented only
  for Unicode engines.)
\item Lithuanian (\texttt{lt}).
  The lowercase letters i and j should retain a dot above when the
  accents grave, acute or tilde are present. This is implemented for
  lowercasing of the relevant uppercase letters both when input as
  single Unicode codepoints and when using combining accents. The
  combining dot is removed when uppercasing in these cases. Note that
  \emph{only} the accents used in Lithuanian are covered: the behaviour
  of other accents are not modified.
\item Dutch (\texttt{nl}).
  Capitalisation of \texttt{ij} at the beginning of titlecased
  input produces \texttt{IJ} rather than \texttt{Ij}. The output
  retains two separate letters, thus this transformation \emph{is}
  available using pdfTeX.
\end{itemize}
\end{function}

\chapter{Files (\texttt{File})}

This module provides functions for working with external files.
%Some of these functions apply to an entire file, and have prefix \cs{file},
%while others are used to work with files on a line by line basis and have
%prefix \cs{Ior} (reading) or \cs{Iow} (writing).

It is important to remember that when reading external files \TeX{}
attempts to locate them using both the operating system path and entries in the
\TeX{} file database (most \TeX{} systems use such a database). Thus the
\enquote{current path} for \TeX{} is somewhat broader than that for other
programs.

For functions which expect a \meta{file name} argument, this argument
may contain both literal items and expandable content, which should on
full expansion be the desired file name.
%Active characters (as declared in \cs{l_char_active_seq}) are \emph{not}
%expanded, allowing the direct use of these in file names.
Quote tokens (\verb|"|) are not permitted in file names as they are reserved
for internal use by some \TeX{} primitives.

Spaces are trimmed at the beginning and end of the file name:
this reflects the fact that some file systems do not allow or interact
unpredictably with spaces in these positions. When no extension is given,
this will trim spaces from the start of the name only.

\section{File Operation Functions}

\begin{function}{\fileInput}
\begin{syntax}
\cs{fileInput} \Arg{file name}
\end{syntax}
Searches for \meta{file name} in the path as detailed for
\cs{fileIfExistTF}, and if found reads in the file and
returns the contents. All files read are recorded
for information and the file name stack is updated by this
function. An error is raised if the file is not found.
\end{function}

\begin{function}{\fileIfExistInput,\fileIfExistInputF}
\begin{syntax}
\cs{fileIfExistInput} \Arg{file name}
\cs{fileIfExistInputF} \Arg{file name} \Arg{false code}
\end{syntax}
Searches for \meta{file name} using the current \TeX{} search path.
%and the additional paths included in \cs{l_file_search_path_seq}.
If found then reads in the file and returns the contents as described
for \cs{fileInput}, otherwise inserts the \meta{false code}.
Note that these functions do not raise
an error if the file is not found, in contrast to \cs{fileInput}.
\end{function}

\begin{function}{\fileGet,\fileGetT,\fileGetF,\fileGetTF}
\begin{syntax}
\cs{fileGet} \Arg{filename} \Arg{setup} \meta{tl}
\cs{fileGetT} \Arg{filename} \Arg{setup} \meta{tl} \Arg{true code}
\cs{fileGetF} \Arg{filename} \Arg{setup} \meta{tl} \Arg{false code}
\cs{fileGetTF} \Arg{filename} \Arg{setup} \meta{tl} \Arg{true code} \Arg{false code}
\end{syntax}
Defines \meta{tl} to the contents of \meta{filename}.
Category codes may need to be set appropriately via the \meta{setup}
argument.
The non-branching version sets the \meta{tl} to \cs{qNoValue} if the file is
not found. The branching version runs the \meta{true code} after the
assignment to \meta{tl} if the file is found, and \meta{false code}
otherwise.
\end{function}

\begin{function}{\fileIfExist,\fileIfExistT,\fileIfExistF,\fileIfExistTF}
\begin{syntax}
\cs{fileIfExist} \Arg{file name}
\cs{fileIfExistT} \Arg{file name} \Arg{true code}
\cs{fileIfExistF} \Arg{file name} \Arg{false code}
\cs{fileIfExistTF} \Arg{file name} \Arg{true code} \Arg{false code}
\end{syntax}
Searches for \meta{file name} using the current \TeX{} search path.
%and the additional paths controlled by \cs{l_file_search_path_seq}.
\end{function}

%\begin{function}{\fileInputStop}
%\begin{syntax}
%\cs{fileInputStop}
%\end{syntax}
%Ends the reading of a file started by \cs{file_input:n} or similar before
%the end of the file is reached. Where the file reading is being terminated
%due to an error, \cs{msg_critical:nn(nn)}
%should be preferred.
%\begin{texnote}
%This function must be used on a line on its own: \TeX{} reads files
%line-by-line and so any additional tokens in the \enquote{current} line
%will still be read.
%\par
%This is also true if the function is hidden inside another function
%(which will be the normal case), i.e., all tokens on the same line
%in the source file are still processed. Putting it on a line by itself
%in the definition doesn't help as it is the line where it is used that
%counts!
%\end{texnote}
%\end{function}

\chapter{Quarks (\texttt{Quark})}

%One special type of constants in \LaTeX3 is \enquote{quarks}.
%By convention all constants of type quark start out with \verb|\q|.

Quarks are control sequences (and in fact, token lists) that expand
to themselves and should therefore \emph{never} be executed directly
in the code. This would result in an endless loop!

Quarks can be used as error return values for functions that receive erroneous input.
For example, in the function \cs{propGet} to retrieve a value stored
in some key of a property list, if the key does not exist then the return value
is the quark \cs{qNoValue}.
As mentioned above, such quarks are extremely fragile and it is imperative
when using such functions that code is carefully written to check for
pathological cases to avoid leakage of a quark into an uncontrolled
environment.

\section{Constant Quarks}

\begin{variable}{\qNoValue}
A canonical value for a missing value, when one is requested from
a data structure. This is therefore used as a \enquote{return} value
by functions such as \cs{propGet} if there is no data to return.
\end{variable}

\section{Quark Conditionals}

\begin{function}{\quarkVarIfNoValue,\quarkVarIfNoValueT,\quarkVarIfNoValueF,\quarkVarIfNoValueTF}
\begin{syntax}
\cs{quarkVarIfNoValue} \meta{token}
\cs{quarkVarIfNoValueT} \meta{token} \Arg{true code}
\cs{quarkVarIfNoValueF} \meta{token} \Arg{false code}
\cs{quarkVarIfNoValueTF} \meta{token} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \meta{token} is equal to \cs{qNoValue}.
\begin{demohigh}
\clistGet \cEmptyClist \lTmpaTl
\quarkVarIfNoValueTF \lTmpaTl {\prgReturn{NoValue}} {\prgReturn{SomeValue}}
\end{demohigh}
\begin{demohigh}
\seqPop \cEmptySeq \lTmpaTl
\quarkVarIfNoValueTF \lTmpaTl {\prgReturn{NoValue}} {\prgReturn{SomeValue}}
\end{demohigh}
\begin{demohigh}
\propSetFromKeyval \lTmpaProp {key1=one,key2=two}
\propGet \lTmpaProp {key3} \lTmpaTl
\quarkVarIfNoValueTF \lTmpaTl {\prgReturn{NoValue}} {\prgReturn{SomeValue}}
\end{demohigh}
\end{function}

%\begin{function}{\quarkIfNoValue,\quarkIfNoValueTF}
%\begin{syntax}
%\cs{quarkIfNoValue} \Arg{token list}
%\cs{quarkIfNoValueTF} \Arg{token list} \Arg{true code} \Arg{false code}
%\end{syntax}
%Tests if the \meta{token list} contains only \cs{qNoValue}
%(distinct from \meta{token list} being empty or containing
%\cs{qNoValue} plus one or more other tokens).
%\end{function}

\chapter{Legacy Concepts (\texttt{Legacy})}

There are a small number of \TeX{} or \LaTeXe{} concepts which are not used
in \pkg{functional} code but which need to be manipulated when working as a \LaTeXe{}
package. To allow these to be integrated cleanly into \pkg{functional} code, a set
of legacy interfaces are provided here.

\begin{function}{\legacyIf,\legacyIfT,\legacyIfF,\legacyIfTF}
\begin{syntax}
\cs{legacyIf} \Arg{name}
\cs{legacyIfT} \Arg{name} \Arg{true code}
\cs{legacyIfF} \Arg{name} \Arg{false code}
\cs{legacyIfTF} \Arg{name} \Arg{true code} \Arg{false code}
\end{syntax}
Tests if the \LaTeXe{}/plain \TeX{} conditional (generated by \tn{newif})
if \texttt{true} or \texttt{false} and branches \hbox{accordingly}. The
\meta{name} of the conditional should \emph{omit} the leading \texttt{if}.
\begin{demohigh}
\newif \ifFooBar
\legacyIfTF {FooBar} {\prgReturn{True!}} {\prgReturn{False!}}
\end{demohigh}
\end{function}

\begin{function}{\legacyIfSetTrue,\legacyIfSetFalse}
\begin{syntax}
\cs{legacyIfSetTrue} \Arg{name}
\cs{legacyIfSetFalse} \Arg{name}
\end{syntax}
Sets the \LaTeXe{}/plain \TeX{} conditional \verb|\if|\meta{name}
(generated by \tn{newif}) to be \texttt{true} or \texttt{false}.
\begin{demohigh}
\newif \ifFooBar
\legacyIfSetTrue {FooBar}
\legacyIfTF {FooBar} {\prgReturn{True!}} {\prgReturn{False!}}
\end{demohigh}
\end{function}

\begin{function}{\legacyIfSet}
\begin{syntax}
\cs{legacyIfSet} \Arg{name} \Arg{boolexpr}
\end{syntax}
Sets the \LaTeXe{}/plain \TeX{} conditional \verb|\if|\meta{name}
(generated by \tn{newif}) to the result of evaluating the
\meta{boolean expression}.
\begin{demohigh}
\newif \ifFooBar
\legacyIfSet {FooBar} {\cFalseBool}
\legacyIfTF {FooBar} {\prgReturn{True!}} {\prgReturn{False!}}
\end{demohigh}
\end{function}

\chapter{The Source Code}

%\CodeHigh{lite}
\dochighinput[language=latex/latex3]{functional.sty}

\end{document}
