% \iffalse meta-comment % %% File: l3flag.dtx % % Copyright (C) 2011-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file % % https://www.latex-project.org/lppl.txt % % This file is part of the "l3kernel bundle" (The Work in LPPL) % and all files in that bundle must be distributed together. % % ----------------------------------------------------------------------- % % The development version of the bundle can be found at % % https://github.com/latex3/latex3 % % for those people who are interested. % %<*driver> \documentclass[full,kernel]{l3doc} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{^^A % The \pkg{l3flag} module\\ Expandable flags^^A % } % % \author{^^A % The \LaTeX{} Project\thanks % {^^A % E-mail: % \href{mailto:latex-team@latex-project.org} % {latex-team@latex-project.org}^^A % }^^A % } % % \date{Released 2024-12-25} % % \maketitle % % \begin{documentation} % % Flags are the only data-type that can be modified in expansion-only % contexts. This module is meant mostly for kernel use: in almost all % cases, booleans or integers should be preferred to flags because they % are very significantly faster. % % A flag can hold any (small) non-negative value, which we call its % \meta{height}. In expansion-only contexts, a flag can only be % \enquote{raised}: this increases the \meta{height} by $1$. The \meta{height} % can also be queried expandably. However, decreasing it, or setting it % to zero requires non-expandable assignments. % % Flag variables are always local. % % A typical use case of flags would be to keep track of whether an % exceptional condition has occurred during expandable processing, and % produce a meaningful (non-expandable) message after the end of the % expandable processing. This is exemplified by \pkg{l3str-convert}, % which for performance reasons performs conversions of individual % characters expandably and for readability reasons produces a single % error message describing incorrect inputs that were encountered. % % Flags should not be used without carefully considering the fact that % raising a flag takes a time and memory proportional to its height and % that the memory cannot be reclaimed even if the flag is cleared. % Flags should not be used unless it is unavoidable. % % In earlier versions, flags were referenced by an \texttt{n}-type % \meta{flag name} such as \texttt{fp_overflow}, used as part of % \cs{use:c} constructions. All of the commands described below have % \texttt{n}-type analogues that can still appear in old code, but the % \texttt{N}-type commands are to be preferred moving forward. The % \texttt{n}-type \meta{flag name} is simply mapped to % \cs[no-index]{l_\meta{flag name}_flag}, which makes it easier for % packages using public flags (such as \pkg{l3fp}) to retain backwards % compatibility. % % \section{Setting up flags} % % \begin{function}[added = 2024-01-12]{\flag_new:N, \flag_new:c} % \begin{syntax} % \cs{flag_new:N} \meta{flag~var} % \end{syntax} % Creates a new \meta{flag~var}, or raises an error if the name is % already taken. The declaration is global, but flags are always local % variables. The \meta{flag~var} initially has zero height. % \end{function} % % \begin{function}[added = 2024-01-12]{\flag_clear:N, \flag_clear:c} % \begin{syntax} % \cs{flag_clear:N} \meta{flag~var} % \end{syntax} % Sets the height of the \meta{flag~var} to zero. The assignment is local. % \end{function} % % \begin{function}[added = 2024-01-12]{\flag_clear_new:N, \flag_clear_new:c} % \begin{syntax} % \cs{flag_clear_new:N} \meta{flag~var} % \end{syntax} % Ensures that the \meta{flag~var} exists globally by applying % \cs{flag_new:N} if necessary, then applies \cs{flag_clear:N}, setting % the height to zero locally. % \end{function} % % \begin{function}[added = 2024-01-12]{\flag_show:N, \flag_show:c} % \begin{syntax} % \cs{flag_show:N} \meta{flag~var} % \end{syntax} % Displays the height of the \meta{flag~var} in the terminal. % \end{function} % % \begin{function}[added = 2024-01-12]{\flag_log:N, \flag_log:c} % \begin{syntax} % \cs{flag_log:N} \meta{flag~var} % \end{syntax} % Writes the height of the \meta{flag~var} in the log file. % \end{function} % % \section{Expandable flag commands} % % \begin{function}[EXP, pTF, added = 2024-01-12]{\flag_if_exist:N, \flag_if_exist:c} % \begin{syntax} % \cs{flag_if_exist_p:N} \meta{flag~var} % \cs{flag_if_exist:NTF} \meta{flag~var} \Arg{true code} \Arg{false code} % \end{syntax} % This function returns \texttt{true} if the \meta{flag~var} is % currently defined, and \texttt{false} otherwise. This does not check % that the \meta{flag~var} really is a flag variable. % \end{function} % % \begin{function}[EXP, pTF, added = 2024-01-12]{\flag_if_raised:N, \flag_if_raised:c} % \begin{syntax} % \cs{flag_if_raised_p:N} \meta{flag~var} % \cs{flag_if_raised:NTF} \meta{flag~var} \Arg{true code} \Arg{false code} % \end{syntax} % This function returns \texttt{true} if the \meta{flag~var} has non-zero % height, and \texttt{false} if the \meta{flag~var} has zero height. % \end{function} % % \begin{function}[EXP, added = 2024-01-12]{\flag_height:N, \flag_height:c} % \begin{syntax} % \cs{flag_height:N} \meta{flag~var} % \end{syntax} % Expands to the height of the \meta{flag~var} as an integer denotation. % \end{function} % % \begin{function}[EXP, added = 2024-01-12]{\flag_raise:N, \flag_raise:c} % \begin{syntax} % \cs{flag_raise:N} \meta{flag~var} % \end{syntax} % The height of \meta{flag~var} is increased by $1$ locally. % \end{function} % % \begin{function}[EXP, added = 2024-01-12]{\flag_ensure_raised:N, \flag_ensure_raised:c} % \begin{syntax} % \cs{flag_ensure_raised:N} \meta{flag~var} % \end{syntax} % Ensures the \meta{flag~var} is raised by making its height at least~$1$, % locally. % \end{function} % % \begin{variable}[added = 2024-01-12]{\l_tmpa_flag, \l_tmpb_flag} % Scratch flag for local assignment. These are never used by % the kernel code, and so are safe for use with any \LaTeX3-defined % function. However, they may be overwritten by other non-kernel % code and so should only be used for short-term storage. % \end{variable} % % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3flag} implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macrocode} %<@@=flag> % \end{macrocode} % % \TestFiles{m3flag001} % % \subsection{Protected flag commands} % % The height $h$ of a flag (which is initially zero) is stored by % setting control sequences of the form \cs[no-index]{\meta{flag % name}\meta{integer}} to \tn{relax} for $0\leq\meta{integer} % \end{macrocode} % % \end{implementation} % % \PrintIndex