summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx
blob: eed657ad231037109bd0464cf938a9f00d82ed09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
% \iffalse meta-comment
%
%% File: l3flag.dtx Copyright (C) 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 "l3experimental 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{expl3}
\GetIdInfo$Id: l3flag.dtx 3039 2011-12-08 09:22:35Z bruno $
  {L3 Experimental Flags}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
\usepackage{amsmath}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
%
% \title{^^A
%   The \textsf{l3flag} package: expandable flags^^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}
%
% Flags are the only data structure on which \TeX{} can perform
% assignments in expansion only contexts. This module is meant
% mostly for kernel use: in almost all cases, booleans should
% be preferred to flags, because they are faster.
%
% A flag can be in two states: \enquote{lowered} or \enquote{raised}.
% The status of a flag can be tested expandably (just like booleans).
% A flag can also be \emph{raised} expandably. However, a flag cannot
% be lowered expandably.
%
% Flag variables are always local.
%
% Testing for the existence of flags with \cs{cs_if_exist:NTF} will
% always result in a negative answer: from the point of view of
% \TeX{}, flags are either undefined control sequences, or let to
% \cs{scan_stop:}. This has a second consequence: flags don't need
% to be declared with \cs{flag_new:N}, although this has error-checking
% benefits. The ability of using flags without declaring them is used
% in \pkg{l3rand}.
%
% \begin{function}{\flag_new:N, \flag_new:c}
%   \begin{syntax}
%     \cs{flag_new:N} \meta{flag}
%   \end{syntax}
%   Creates a new \meta{flag} or raises an error if the
%   name is already taken. The declaration is global,
%   but \meta{flags} are always local variables.
%   The \meta{flag} will initially be lowered.
% \end{function}
%
% \begin{function}[EXP,pTF]{\flag_test:N, \flag_test:c}
%   \begin{syntax}
%     \cs{flag_test:N} \meta{flag}
%   \end{syntax}
%   This function returns \texttt{true} if the \meta{flag} is raised,
%   and \texttt{false} if the \meta{flag} is lowered.
% \end{function}
%
% \begin{function}[EXP]{\flag_raise:N}
%   \begin{syntax}
%     \cs{flag_raise:N} \meta{flag}
%   \end{syntax}
%   The \meta{flag} is raised. The assignment is local.
%   This function is expandable, despite being an assignment.
% \end{function}
%
% \begin{function}{\flag_lower:N}
%   \begin{syntax}
%     \cs{flag_lower:N} \meta{flag}
%   \end{syntax}
%   The \meta{flag} is lowered. The assignment is local.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3str} implementation}
%
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
%    \begin{macrocode}
\ProvidesExplPackage
  {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
%    \end{macrocode}
%
% \begin{variable}{\g_flag_list_tl}
%   We keep track of the list of all defined flags in a token list.
%   This is only used by \cs{flag_new:N} to check that the flag
%   has not yet been defined.
%    \begin{macrocode}
\tl_new:N \g_flag_list_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\flag_new:N, \flag_new:c}
%   If the control sequence is already defined, then we raise an error.
%   Otherwise we check if it is already a flag, raising an appropriate
%   error, finally lower the flag globally (this is the only global
%   assignment to a flag\ldots{} perhaps an error?).
%   The \texttt{c} variant can be created without worrying for this function.
%   \begin{macrocode}
\cs_new_protected:Npn \flag_new:N #1
  {
    \tl_if_in:NnTF \g_flag_list_tl {#1}
      {
        \msg_kernel_error:nnx
          { flag } { already-defined }
          { \token_to_str:N #1 }
      }
      {
        \tl_gput_right:Nn \g_flag_list_tl {#1}
        \cs_new_eq:NN #1 \c_undefined:D
      }
  }
\cs_generate_variant:Nn \flag_new:N { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP, pTF]{\flag_test:N, \flag_test:c}
%   Test if the control sequence is \texttt{undefined} or not.
%    \begin{macrocode}
\prg_new_conditional:Npnn \flag_test:N #1 { p , T , F , TF }
  {
    \if_cs_exist:N #1
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\prg_new_conditional:Npnn \flag_test:c #1 { p , T , F , TF }
  {
    \if_cs_exist:w #1 \cs_end:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\flag_raise:N, \flag_raise:c}
%   Raising a flag expandably relies on the fact that \TeX{}
%   automatically lets undefined control sequences to \tn{relax}
%   when building an unknown csname. We build such a csname, then
%   remove it with \cs{use_none:n}, essentially doing
%   \cs{use_none:c}, but optimized slightly. When a flag is given
%   as an \texttt{N}-type argument, a little more work is needed,
%   converting to a csname before raising that.
%    \begin{macrocode}
\cs_new:Npn \flag_raise:N #1
  { \exp_after:wN \use_none:n \cs:w \cs_to_str:N #1 \cs_end: }
\cs_new:Npn \flag_raise:c #1
  { \exp_after:wN \use_none:n \cs:w #1 \cs_end: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\flag_lower:N, \flag_lower:c}
%   Simply undefine the control sequence, locally.
%    \begin{macrocode}
\cs_new_protected:Npn \flag_lower:N #1
  { \cs_set_eq:NN #1 \c_undefined:D }
\cs_generate_variant:Nn \flag_lower:N { c }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\msg_kernel_new:nnnn { flag } { already-defined }
  { The~control~sequence~#1~is~already~declared~as~a~flag. }
  {
    LaTeX~was~asked~to~define~the~flag~#1,~but~it~has~already~
    been~defined~as~a~flag.~The~flag~module~is~mostly~meant~
    for~kernel~use,~and~booleans~should~be~preferred.
  }
%    \end{macrocode}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex