summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-03-05 22:35:14 +0000
committerKarl Berry <karl@freefriends.org>2019-03-05 22:35:14 +0000
commit68872ff6a2a91fa0e84763fc9316493d82075c95 (patch)
tree0546ec4c414553802e31a423aec44f74d252f645 /Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
parent541c4ddf7c5b402b9cfe8af5ef4e49ffa15d3e83 (diff)
l3 (5mar19)
git-svn-id: svn://tug.org/texlive/trunk@50246 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3expan.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3expan.dtx138
1 files changed, 113 insertions, 25 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
index dd4d70f59d6..4748bf35aa3 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
%
% \maketitle
%
@@ -713,7 +713,7 @@
% \cs{exp_not:o} \Arg{tokens}
% \end{syntax}
% Expands the \meta{tokens} once, then prevents any further expansion
-% in |x|-type arguments using \cs{exp_not:n}.
+% in |x|-type or \texttt{e}-type arguments using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:V}
@@ -721,7 +721,7 @@
% \cs{exp_not:V} \meta{variable}
% \end{syntax}
% Recovers the content of the \meta{variable}, then prevents expansion
-% of this material in |x|-type arguments using \cs{exp_not:n}.
+% of this material in |x|-type or \texttt{e}-type arguments using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:v}
@@ -732,7 +732,7 @@
% converts this into a control sequence which should be a \meta{variable}
% name.
% The content of the \meta{variable} is recovered, and further
-% expansion in |x|-type arguments is prevented using \cs{exp_not:n}.
+% expansion in |x|-type or \texttt{e}-type arguments is prevented using \cs{exp_not:n}.
% \begin{texnote}
% Protected macros that appear in a \texttt{v}-type argument are
% expanded despite being protected; \cs{exp_not:n} also has no
@@ -759,7 +759,7 @@
% Expands \meta{tokens} fully until the first unexpandable token is
% found (if it is a space it is removed). Expansion then stops, and
% the result of the expansion (including any tokens which were not
-% expanded) is protected from further expansion in |x|-type arguments
+% expanded) is protected from further expansion in |x|-type or \texttt{e}-type arguments
% using \cs{exp_not:n}.
% \end{function}
%
@@ -1783,13 +1783,18 @@
{
% \end{macrocode}
%
-% \begin{macro}[EXP]{\@@_e:nn}
+% \begin{macro}[EXP]{\@@_e:nn, \@@_e_end:nn}
% Repeatedly expand tokens, keeping track of fully-expanded tokens in
% the second argument to \cs{@@_e:nn}; this function eventually
% calls \cs{@@_e_end:nn} to leave \cs{exp_end:} in the input
% stream, followed by the result of the expansion. There are many
% special cases: spaces, brace groups, \tn{noexpand}, \tn{unexpanded},
% \tn{the}, \tn{primitive}.
+% While we use brace tricks \cs{if_false:} |{| \cs{fi:}, the expansion
+% of this function is always triggered by \cs{exp:w} so brace balance
+% is eventually restored after that is hit with a single step of
+% expansion. Otherwise we could not nest \texttt{e}-type expansions
+% within each other.
% \begin{macrocode}
\cs_new:Npn \@@_e:nn #1
{
@@ -1844,7 +1849,8 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\@@_e:N}
+% \begin{macro}[EXP]
+% {\@@_e:N, \@@_e:Nnn, \@@_e_protected:Nnn, \@@_e_expandable:Nnn}
% For an \texttt{N}-type token, call \cs{@@_e:Nnn} with arguments the
% \meta{first token}, the remaining tokens to expand and what's
% already been expanded. If the \meta{first token} is non-expandable,
@@ -1887,14 +1893,74 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\@@_e_primitive:Nnn}
-% Quite rare. Will be implemented later.
+% \begin{macro}[EXP]
+% {
+% \@@_e_primitive:Nnn,
+% \@@_e_primitive_aux:NNw,
+% \@@_e_primitive_aux:NNnn,
+% \@@_e_primitive_other:NNnn,
+% \@@_e_primitive_other_aux:nNNnn
+% }
+% We don't try hard to make sensible error recovery since the error
+% recovery of \cs{tex_primitive:D} when followed by something else
+% than a primitive depends on the engine. The only valid case is when
+% what follows is \texttt{N}-type. Then distinguish special
+% primitives \tn{unexpanded}, \tn{noexpand}, \tn{the}, \tn{primitive}
+% from other primitives. In the \enquote{other} case, the only
+% reasonable way to check if the primitive that follows
+% \cs{tex_primitive:D} is expandable is to expand and compare the
+% before-expansion and after-expansion results. If they coincide then
+% probably the primitive is non-expandable and should be put in the
+% output together with \cs{tex_primitive:D} (one can cook up contrived
+% counter-examples where the true \tn{expanded} would have an infinite
+% loop), and otherwise one should continue expanding.
% \begin{macrocode}
- \cs_new:Npn \@@_e_primitive:Nnn #1
+ \cs_new:Npn \@@_e_primitive:Nnn #1#2
{
- \__kernel_msg_expandable_error:nnn { kernel } { e-type }
- { \primitive not~implemented }
- \@@_e:nn
+ \if_false: { \fi:
+ \tl_if_head_is_N_type:nTF {#2}
+ { \@@_e_primitive_aux:NNw #1 }
+ {
+ \__kernel_msg_expandable_error:nnn { kernel } { e-type }
+ { Missing~primitive~name }
+ \@@_e_primitive_aux:NNw #1 \c_empty_tl
+ }
+ #2
+ }
+ }
+ \cs_new:Npn \@@_e_primitive_aux:NNw #1#2
+ {
+ \exp_after:wN \@@_e_primitive_aux:NNnn
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \if_false: } \fi:
+ }
+ \cs_new:Npn \@@_e_primitive_aux:NNnn #1#2
+ {
+ \exp_args:Nf \str_case_e:nnTF { \cs_to_str:N #2 }
+ {
+ { unexpanded } { \@@_e_unexpanded:Nnn \exp_not:n }
+ { noexpand } { \@@_e_noexpand:Nnn \exp_not:N }
+ { the } { \@@_e_the:Nnn \tex_the:D }
+ {
+ \sys_if_engine_xetex:T { pdf }
+ \sys_if_engine_luatex:T { pdf }
+ primitive
+ } { \@@_e_primitive:Nnn #1 }
+ }
+ { \@@_e_primitive_other:NNnn #1 #2 }
+ }
+ \cs_new:Npn \@@_e_primitive_other:NNnn #1#2#3
+ {
+ \exp_args:No \@@_e_primitive_other_aux:nNNnn
+ { #1 #2 #3 }
+ #1 #2 {#3}
+ }
+ \cs_new:Npn \@@_e_primitive_other_aux:nNNnn #1#2#3#4#5
+ {
+ \str_if_eq:nnTF {#1} { #2 #3 #4 }
+ { \@@_e:nn {#4} { #5 #2 #3 } }
+ { \@@_e:nn {#1} {#5} }
}
% \end{macrocode}
% \end{macro}
@@ -1937,10 +2003,10 @@
% braces), unless that \meta{token} is \cs{scan_stop:} or a space
% (recall that we don't implement the case of an implicit begin-group
% token). An expandable \meta{token} is instead expanded, unless it
-% is \tn{noexpand}. That primitive can be followed by an expandable
-% \texttt{N}-type token, to be removed, by a non-expandable one, kept
-% (and later causing an error), by a space, removed by
-% \texttt{f}-expansion, or by a brace group or nothing (later causing
+% is \tn{noexpand}. The latter primitive can be followed by an expandable
+% \texttt{N}-type token (removed), by a non-expandable one (kept
+% and later causing an error), by a space (removed by
+% \texttt{f}-expansion), or by a brace group or nothing (later causing
% an error).
% \begin{macrocode}
\cs_new:Npn \@@_e_unexpanded:Nnn #1 { \@@_e_unexpanded:nn }
@@ -2098,20 +2164,41 @@
{
#1
\exp_after:wN \@@_e_the_toks:n
+ \exp_after:wN { \if_false: } \fi:
+ }
+ {
+ \exp_after:wN ;
+ \exp_after:wN { \if_false: } \fi: #1
}
- { \exp_after:wN ; }
- \exp_after:wN { \if_false: } \fi:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_e_if_toks_register:NTF}
-% We need to detect both \tn{toks} registers like \tn{toks@} (in
-% \LaTeXe{}) and parameters such as \tn{everypar}, as the result of
-% unpacking the register should not expand further. The list of
-% parameters is finite so we just use a \cs{cs_if_exist:cTF} test to
-% look up in a table. Registers are found by
-% \cs{token_if_toks_register:NTF} by inspecting the meaning. We abuse
+% \begin{macro}[EXP]
+% {
+% \@@_e_the_XeTeXinterchartoks:,
+% \@@_e_the_errhelp:,
+% \@@_e_the_everycr:,
+% \@@_e_the_everydisplay:,
+% \@@_e_the_everyeof:,
+% \@@_e_the_everyhbox:,
+% \@@_e_the_everyjob:,
+% \@@_e_the_everymath:,
+% \@@_e_the_everypar:,
+% \@@_e_the_everyvbox:,
+% \@@_e_the_output:,
+% \@@_e_the_pdfpageattr:,
+% \@@_e_the_pdfpageresources:,
+% \@@_e_the_pdfpagesattr:,
+% \@@_e_the_pdfpkmode:
+% }
+% We need to detect both \tn{toks} registers like \tn{toks@} in
+% \LaTeXe{} and parameters such as \tn{everypar}, as the result of
+% unpacking the register should not expand further. Registers are
+% found by \cs{token_if_toks_register:NTF} by inspecting the meaning.
+% The list of parameters is finite so we just use a
+% \cs{cs_if_exist:cTF} test to look up in a table. We abuse
% \cs{cs_to_str:N}'s ability to remove a leading escape character
% whatever it is.
% \begin{macrocode}
@@ -2145,6 +2232,7 @@
\cs_new_eq:NN \@@_e_the_pdfpkmode: ?
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% We are done emulating \texttt{e}-type argument expansion when
% \tn{expanded} is unavailable.