summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel/l3text.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3text.dtx')
-rw-r--r--macros/latex/contrib/l3kernel/l3text.dtx67
1 files changed, 53 insertions, 14 deletions
diff --git a/macros/latex/contrib/l3kernel/l3text.dtx b/macros/latex/contrib/l3kernel/l3text.dtx
index 046bf68677..aee505c0c5 100644
--- a/macros/latex/contrib/l3kernel/l3text.dtx
+++ b/macros/latex/contrib/l3kernel/l3text.dtx
@@ -43,14 +43,12 @@
% }^^A
% }
%
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
%
% \maketitle
%
% \begin{documentation}
%
-% \section{\pkg{l3text} documentation}
-%
% 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,
@@ -58,7 +56,7 @@
% operate by expansion. Begin-group and end-group tokens in the \meta{text}
% are normalized and become |{| and |}|, respectively.
%
-% \subsection{Expanding text}
+% \section{Expanding text}
%
% \begin{function}[EXP, added = 2020-01-02]{\text_expand:n}
% \begin{syntax}
@@ -89,7 +87,7 @@
% should be expandable.
% \end{function}
%
-% \subsection{Case changing}
+% \section{Case changing}
%
% \begin{function}[EXP, added = 2019-11-20, updated = 2020-02-24]
% {
@@ -196,7 +194,7 @@
% character is uppercased, and the rest lowercased, irrespective of the nature
% of the character.
%
-% \subsection{Removing formatting from text}
+% \section{Removing formatting from text}
%
% \begin{function}[EXP, added = 2020-03-05, updated = 2020-05-14]{\text_purify:n}
% \begin{syntax}
@@ -226,7 +224,7 @@
% should be expandable.
% \end{function}
%
-% \subsection{Control variables}
+% \section{Control variables}
%
% \begin{variable}{\l_text_accents_tl}
% Lists commands which represent accents, and which are left unchanged
@@ -639,7 +637,10 @@
% \begin{macro}[EXP]{\@@_expand_replace:N}
% \begin{macro}[EXP]{\@@_expand_replace:n}
% \begin{macro}[EXP]{\@@_expand_cs_expand:N}
-% \begin{macro}[EXP]{\@@_expand_noexpand:nn}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:w}
+% \begin{macro}[EXP]{\@@_expand_unexpanded_test:w}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:N}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:n}
% After precautions against |&| tokens, start a simple loop: that of
% course means that \enquote{text} cannot contain the two recursion
% quarks. The loop here must be \texttt{f}-type expandable; we have
@@ -998,14 +999,13 @@
% Finally, expand any macros which can be: this then loops back around to
% deal with what they produce. The only issue is if the token is
% \cs{exp_not:n}, as that must apply to the following balanced text.
-% There might be an \cs{exp_after:wN} there, so we check for it.
% \begin{macrocode}
\cs_new:Npn \@@_expand_cs_expand:N #1
{
\@@_if_expandable:NTF #1
{
\token_if_eq_meaning:NNTF #1 \exp_not:n
- { \@@_expand_noexpand:w }
+ { \@@_expand_unexpanded:w }
{ \exp_after:wN \@@_expand_loop:w #1 }
}
{
@@ -1013,11 +1013,47 @@
\@@_expand_loop:w
}
}
-\cs_new:Npn \@@_expand_noexpand:w #1#
- { \@@_expand_noexpand:nn {#1} }
-\cs_new:Npn \@@_expand_noexpand:nn #1#2
+% \end{macrocode}
+% Since \cs{exp_not:n} is actually a primitive, it allows a strange syntax
+% and it particular the primitive expands what follows and discards spaces
+% and \cs{scan_stop:} until finding a braced argument (the opening brace
+% can be implicit but we will not support this here). Here, we repeatedly
+% |f|-expand after such an \cs{exp_not:n}, and test what follows. If
+% it is a brace group, then we found the intended argument of
+% \cs{exp_not:n}. If it is a space, then the next |f|-expansion will
+% eliminate it. If it is an |N|-type token then
+% \cs{@@_expand_unexpanded:N} leaves the token to be expanded if it is
+% expandable, and otherwise removes it, assuming that it is
+% \cs{scan_stop:}. This silently hides errors when \cs{exp_not:n} is
+% incorrectly followed by some non-expandable token other than
+% \cs{scan_stop:}, but this should be pretty rare, and there is no good
+% error recovery anyways.
+% \begin{macrocode}
+\cs_new:Npn \@@_expand_unexpanded:w
+ {
+ \exp_after:wN \@@_expand_unexpanded_test:w
+ \exp:w \exp_end_continue_f:w
+ }
+\cs_new:Npn \@@_expand_unexpanded_test:w #1 \q_@@_recursion_stop
+ {
+ \tl_if_head_is_group:nTF {#1}
+ { \@@_expand_unexpanded:n }
+ {
+ \@@_expand_unexpanded:w
+ \tl_if_head_is_N_type:nT {#1} { \@@_expand_unexpanded:N }
+ }
+ #1 \q_@@_recursion_stop
+ }
+\cs_new:Npn \@@_expand_unexpanded:N #1
{
- #1 \@@_expand_store:n #1 {#2}
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \else:
+ \exp_after:wN #1
+ \fi:
+ }
+\cs_new:Npn \@@_expand_unexpanded:n #1
+ {
+ \@@_expand_store:n {#1}
\@@_expand_loop:w
}
% \end{macrocode}
@@ -1052,6 +1088,9 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}
% {