% \iffalse meta-comment
%
%% File: l3quark.dtx Copyright (C) 1990-2011 The LaTeX3 Project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the "l3kernel bundle" (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX3 Project.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
\GetIdInfo$Id: l3quark.dtx 3014 2011-11-27 06:55:43Z bruno $
  {L3 Experimental quarks}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3quark} package\\ Quarks^^A
%   \thanks{This file describes v\ExplFileVersion,
%      last revised \ExplFileDate.}^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released \ExplFileDate}
%
% \maketitle
%
% \begin{documentation}
%
% A special type of constants in \LaTeX3 are \enquote{quarks}. These are
% control
% sequences that expand to themselves and should therefore \emph{never} be
% executed directly in the code. This would result in an endless loop!
%
% They are meant to be used as delimiter is weird functions (for
% example as the stop token (\emph{i.e.}~\cs{q_stop}). They also permit the
% following ingenious trick: when you pick up a token in a temporary,
% and you want to know whether you have picked up a particular quark,
% all you have to do is compare the temporary to the quark using
% \cs{if_meaning:w}. A set of special quark testing functions is set up
% below. All the quark testing functions are expandable although the
% ones testing only single tokens are much faster.
%
% By convention all constants of type quark start out with |\q_|.
%
% \section{Defining quarks}
%
% \begin{function}{\quark_new:N}
%   \begin{syntax}
%     \cs{quark_new:N} \meta{quark}
%   \end{syntax}
%   Creates a new \meta{quark} which expands only to \meta{quark}.
%   The \meta{quark} will be defined globally, and an error message
%   will be raised if the name was already taken.
% \end{function}
%
% \begin{variable}{\q_stop}
%   Used as a marker for delimited arguments, such as
%   \begin{verbatim}
%     \cs_set:Npn \tmp:w #1#2 \q_stop {#1}
%   \end{verbatim}
% \end{variable}
%
% \begin{variable}{\q_mark}
%   Used as a marker for delimited arguments when \cs{q_stop} is
%   already in use.
% \end{variable}
%
% \begin{variable}{\q_nil}
%   Quark to mark a null value in structured variables or functions. Used
%   as an end delimiter when this may itself may need to be tested
%   (in contrast to \cs{q_stop}, which is only ever used as a delimiter).
% \end{variable}
%
% \begin{variable}{\q_no_value}
%   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{prop_get:NnN} if there is no data to
%   return.
% \end{variable}
%
% \section{Quark tests}
%
% The method used to define quarks means that the single token (\texttt{N})
% tests are faster than the multi-token (\texttt{n}) tests. The later
% should therefore only be used when the argument can definitely take
% more than a single token.
%
% \begin{function}[EXP,pTF]{\quark_if_nil:N}
%   \begin{syntax}
%     \cs{quark_if_nil_p:N} \meta{token}
%     \cs{quark_if_nil:NTF} \meta{token} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Tests if the \meta{token} is equal to \cs{q_nil}.
% \end{function}
%
% \begin{function}[EXP,pTF]{\quark_if_nil:n, \quark_if_nil:o, \quark_if_nil:V}
%   \begin{syntax}
%     \cs{quark_if_nil_p:n} \Arg{token list} \\
%     \cs{quark_if_nil:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Tests if the \meta{token list} contains only \cs{q_nil} (distinct
%   from \meta{token list} being empty or containing \cs{q_nil} plus one
%   or more other tokens).
% \end{function}
%
% \begin{function}[EXP,pTF]{\quark_if_no_value:N, \quark_if_no_value:c}
%   \begin{syntax}
%     \cs{quark_if_no_value_p:N} \meta{token} \\
%     \cs{quark_if_no_value:NTF} \meta{token} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Tests if the \meta{token} is equal to \cs{q_no_value}.
% \end{function}
%
% \begin{function}[EXP,pTF]{\quark_if_no_value:n}
%   \begin{syntax}
%      \cs{quark_if_no_value_p:n} \Arg{token list} \\
%     \cs{quark_if_no_value:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Tests if the \meta{token list} contains only \cs{q_no_value}
%   (distinct from \meta{token list} being empty or containing
%   \cs{q_no_value} plus one or more other tokens).
% \end{function}
%
% \section{Recursion}
%
% This module provides a uniform interface to intercepting and
% terminating loops as when one is doing tail recursion. The building
% blocks follow below.
%
% \begin{variable}{\q_recursion_tail}
%   This quark is appended to the data structure in question and
%   appears as a real element there. This means it gets any list
%   separators around it.
% \end{variable}
%
% \begin{variable}{\q_recursion_stop}
%   This quark is added \emph{after} the data structure. Its purpose
%   is to make it possible to terminate the recursion at any point
%   easily.
% \end{variable}
%
% \begin{function}{\quark_if_recursion_tail_stop:N}
%   \begin{syntax}
%     \cs{quark_if_recursion_tail_stop:N} \meta{token}
%   \end{syntax}
%   Tests if \meta{token} contains only the marker
%   \cs{q_recursion_tail}, and if so terminates the recursion this is
%   part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
%   recursion input must include the marker tokens \cs{q_recursion_tail}
%   and \cs{q_recursion_stop} as the last two items.
% \end{function}
%
% \begin{function}[updated = 2011-09-06]
%   {\quark_if_recursion_tail_stop:n, \quark_if_recursion_tail_stop:o}
%   \begin{syntax}
%     \cs{quark_if_recursion_tail_stop:n} \Arg{token list}
%   \end{syntax}
%   Tests if the \meta{token list} contains only
%   \cs{q_recursion_tail}, and if so terminates the recursion this is
%   part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
%   recursion input must include the marker tokens \cs{q_recursion_tail}
%   and \cs{q_recursion_stop} as the last two items.
% \end{function}
%
% \begin{function}{\quark_if_recursion_tail_stop_do:Nn}
%   \begin{syntax}
%     \cs{quark_if_recursion_tail_stop_do:Nn} \meta{token} \Arg{insertion}
%   \end{syntax}
%   Tests if \meta{token} contains only the marker
%   \cs{q_recursion_tail}, and if so terminates the recursion this is
%   part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
%   recursion input must include the marker tokens \cs{q_recursion_tail}
%   and \cs{q_recursion_stop} as the last two items. The \meta{insertion}
%   code is then added to the input stream after the recursion has
%   ended.
% \end{function}
%
% \begin{function}[updated = 2011-09-06]
%   {\quark_if_recursion_tail_stop_do:nn, \quark_if_recursion_tail_stop_do:on}
%   \begin{syntax}
%     \cs{quark_if_recursion_tail_stop_do:nn} \Arg{token list} \Arg{insertion}
%   \end{syntax}
%   Tests if the \meta{token list} contains only
%   \cs{q_recursion_tail}, and if so terminates the recursion this is
%   part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
%   recursion input must include the marker tokens \cs{q_recursion_tail}
%   and \cs{q_recursion_stop} as the last two items. The \meta{insertion}
%   code is then added to the input stream after the recursion has
%   ended.
% \end{function}
%
% \begin{function}
%   {
%     \quark_if_recursion_tail_break:N,
%     \quark_if_recursion_tail_break:n
%   }
%   \begin{syntax}
%     \cs{quark_if_recursion_tail_break:n} \Arg{token list}
%   \end{syntax}
%   Tests if \meta{token list} contains only \cs{q_recursion_tail},
%   and if so terminates the recursion using \cs{prg_map_break:}.
%   The recursion end should be marked by \cs{prg_break_point:n}.
% \end{function}
%
% \section{Internal quark functions}
%
% \begin{function}{\use_none_delimit_by_q_recursion_stop:w}
%   \begin{syntax}
%     \cs{use_none_delimit_by_q_recursion_stop:w} \meta{tokens} \cs{q_recursion_stop}
%   \end{syntax}
%   Used to prematurely terminate a recursion using \cs{q_recursion_stop}
%   as the end marker, removing any remaining \meta{tokens} from the
%   input stream.
% \end{function}
%
% \begin{function}{\use_i_delimit_by_q_recursion_stop:nw}
%   \begin{syntax}
%     \cs{use_i_delimit_by_q_recursion_stop:nw} \Arg{insertion}
%     ~~\meta{tokens} \cs{q_recursion_stop}
%   \end{syntax}
%   Used to prematurely terminate a recursion using \cs{q_recursion_stop}
%   as the end marker, removing any remaining \meta{tokens} from the
%   input stream. The \meta{insertion} is then made into the input
%   stream after the end of the recursion.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3quark} implementation}
%
% \TestFiles{m3quark001.lvt}
%
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\package_check_loaded_expl:
%</package>
%    \end{macrocode}
%
% \begin{macro}{\quark_new:N}
% \UnitTested
%    Allocate a new quark.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \quark_new:N #1 { \tl_const:Nn #1 {#1} }
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}{\q_nil, \q_mark, \q_no_value, \q_stop}
%   Some \enquote{public} quarks. \cs{q_stop} is an \enquote{end of
%   argument} marker, \cs{q_nil} is a empty value and \cs{q_no_value}
%   marks an empty argument.
%    \begin{macrocode}
\quark_new:N \q_nil
\quark_new:N \q_mark
\quark_new:N \q_no_value
\quark_new:N \q_stop
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\q_recursion_tail,\q_recursion_stop}
%   Quarks for ending recursions. Only ever used there!
%   \cs{q_recursion_tail} is appended to whatever list structure we are
%   doing recursion on, meaning it is added as a proper list item with
%   whatever list separator is in use.  \cs{q_recursion_stop} is placed
%   directly after the list.
%    \begin{macrocode}
\quark_new:N \q_recursion_tail
\quark_new:N \q_recursion_stop
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\quark_if_recursion_tail_stop:N}
% \UnitTested
% \begin{macro}{\quark_if_recursion_tail_stop_do:Nn}
% \UnitTested
%   When doing recursions, it is easy to spend a lot of time testing if the
%   end marker has been found. To avoid this, a dedicated end marker is used
%   each time a recursion is set up. Thus if the marker is found everything
%   can be wrapper up and finished off. The simple case is when the test
%   can guarantee that only a single token is being tested. In this case,
%   there is just a dedicated copy of the standard quark test. Both a gobbling
%   version and one inserting end code are provided.
%    \begin{macrocode}
\cs_new:Npn \quark_if_recursion_tail_stop:N #1
  {
    \if_meaning:w \q_recursion_tail #1
      \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
    \fi:
  }
\cs_new:Npn \quark_if_recursion_tail_stop_do:Nn #1
  {
    \if_meaning:w \q_recursion_tail #1
      \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
    \else:
      \exp_after:wN \use_none:n
    \fi:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}
%   {\quark_if_recursion_tail_stop:n,\quark_if_recursion_tail_stop:o}
% \UnitTested
% \begin{macro}
%   {\quark_if_recursion_tail_stop_do:nn,\quark_if_recursion_tail_stop_do:on}
% \UnitTested
%   The same idea applies when testing multiple tokens, but here we just
%   compare the token list to \cs{q_recursion_tail} as a string.
%    \begin{macrocode}
\cs_new:Npn \quark_if_recursion_tail_stop:n #1
  {
    \if_int_compare:w \pdftex_strcmp:D
      { \exp_not:N \q_recursion_tail } { \exp_not:n {#1} } = \c_zero
      \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
    \fi:
  }
\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1
  {
    \if_int_compare:w \pdftex_strcmp:D
      { \exp_not:N \q_recursion_tail } { \exp_not:n {#1} } = \c_zero
      \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
    \else:
      \exp_after:wN \use_none:n
    \fi:
  }
\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n { o }
\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn { o }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\quark_if_recursion_tail_break:N}
% \begin{macro}{\quark_if_recursion_tail_break:n}
%   Analogs of the \cs{quark_if_recursion_tail_stop\ldots{}} functions.
%   Break the mapping using \cs{prg_map_break:}.
%    \begin{macrocode}
\cs_new:Npn \quark_if_recursion_tail_break:N #1
  {
    \if_meaning:w \q_recursion_tail #1
      \exp_after:wN \prg_map_break:
    \fi:
  }
\cs_new:Npn \quark_if_recursion_tail_break:n #1
  {
    \if_int_compare:w \pdftex_strcmp:D
      { \exp_not:N \q_recursion_tail } { \exp_not:n {#1} } = \c_zero
      \exp_after:wN \prg_map_break:
    \fi:
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[pTF]{\quark_if_nil:N}
% \UnitTested
% \begin{macro}[pTF]{\quark_if_no_value:N., \quark_if_no_value:c}
% \UnitTested
%   Here we test if we found a special quark as the first argument.
%   We better start with \cs{q_no_value} as the first argument since
%   the whole thing may otherwise loop if |#1| is wrongly given
%   a string like |aabc| instead of a single token.\footnote{It may
%   still loop in special circumstances however!}
%    \begin{macrocode}
\prg_new_conditional:Nnn \quark_if_nil:N { p, T , F , TF }
  {
    \if_meaning:w \q_nil #1
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\prg_new_conditional:Nnn \quark_if_no_value:N { p, T , F , TF }
  {
    \if_meaning:w \q_no_value #1
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_generate_variant:Nn \quark_if_no_value_p:N { c }
\cs_generate_variant:Nn \quark_if_no_value:NT  { c }
\cs_generate_variant:Nn \quark_if_no_value:NF  { c }
\cs_generate_variant:Nn \quark_if_no_value:NTF { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[pTF]{\quark_if_nil:n, \quark_if_nil:V, \quark_if_nil:o}
% \UnitTested
% \begin{macro}[pTF]{\quark_if_no_value:n}
% \UnitTested
%   These are essentially \cs{str_if_eq:nn} tests but done directly.
%    \begin{macrocode}
\prg_new_conditional:Nnn \quark_if_nil:n { p, T , F , TF }
  {
    \if_int_compare:w \pdftex_strcmp:D
      { \exp_not:N \q_nil } { \exp_not:n {#1} } = \c_zero
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\prg_new_conditional:Nnn \quark_if_no_value:n { p, T , F , TF }
  {
    \if_int_compare:w \pdftex_strcmp:D
      { \exp_not:N \q_no_value } { \exp_not:n {#1} } = \c_zero
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_generate_variant:Nn \quark_if_nil_p:n { V , o }
\cs_generate_variant:Nn \quark_if_nil:nTF { V , o }
\cs_generate_variant:Nn \quark_if_nil:nT  { V , o }
\cs_generate_variant:Nn \quark_if_nil:nF  { V , o }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{variable}{\q_tl_act_mark,\q_tl_act_stop}
%   These private quarks are needed by \pkg{l3tl}, but that is loaded
%   before the quark module, hence their definition is deferred.
%    \begin{macrocode}
\quark_new:N \q_tl_act_mark
\quark_new:N \q_tl_act_stop
%    \end{macrocode}
% \end{variable}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
%
% \endinput
