[latex3-commits] [git/LaTeX3-latex3-latex3] l3text: Make finding math-in-text f-type expandable (86bfc62cc)
Joseph Wright
joseph.wright at morningstar2.co.uk
Sun Dec 8 23:32:04 CET 2019
Repository : https://github.com/latex3/latex3
On branch : l3text
Link : https://github.com/latex3/latex3/commit/86bfc62ccda57de71ed51ee234b61b811217f946
>---------------------------------------------------------------
commit 86bfc62ccda57de71ed51ee234b61b811217f946
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date: Sun Dec 8 21:07:18 2019 +0000
Make finding math-in-text f-type expandable
This then allows a 'follow-on' command:
currently the no-op and the simple (hyperref-like)
approaches are available.
>---------------------------------------------------------------
86bfc62ccda57de71ed51ee234b61b811217f946
l3kernel/l3text.dtx | 234 ++++++++++++++++++++++++++------
l3kernel/testfiles/m3text003.luatex.tlg | 2 +-
l3kernel/testfiles/m3text003.ptex.tlg | 2 +-
l3kernel/testfiles/m3text003.tlg | 2 +-
l3kernel/testfiles/m3text003.uptex.tlg | 2 +-
l3kernel/testfiles/m3text003.xetex.tlg | 2 +-
6 files changed, 199 insertions(+), 45 deletions(-)
diff --git a/l3kernel/l3text.dtx b/l3kernel/l3text.dtx
index 8bff981dd..494e3b340 100644
--- a/l3kernel/l3text.dtx
+++ b/l3kernel/l3text.dtx
@@ -167,12 +167,13 @@
% \end{syntax}
% Takes user input \meta{text} and expands as described for
% \cs{text_expand:n}, then removes all functions from the resulting
-% text. No processing takes place of math mode material (as delimited by
-% pairs given in \cs{l_text_math_delims_tl} or as the argument to commands
-% listed in \cs{l_text_math_arg_tl}); these tokens and functions are left
-% in-place. Non-expandable functions present in the \meta{text} must either
-% have a defined equivalent (see \cs{text_declare_purify_equivalent:Nn})
-% or will be removed from the result.
+% text. Math mode material (as delimited by pairs given in
+% \cs{l_text_math_delims_tl} or as the argument to commands listed in
+% \cs{l_text_math_arg_tl}) is processed as determined by the current
+% setting for \cs{text_set_purify_math_mode:n}, and is left contained
+% in a pair of delimiters. Non-expandable functions present in the
+% \meta{text} must either have a defined equivalent (see
+% \cs{text_declare_purify_equivalent:Nn}) or will be removed from the result.
% \end{function}
%
% \begin{function}[added = 2019-12-05]
@@ -188,6 +189,36 @@
% should be expandable.
% \end{function}
%
+% \begin{function}[rEXP, added = 2019-12-08]
+% {
+% \text_purify_math_unchanged:n,
+% \text_purify_math_chars:n
+% }
+% \begin{syntax}
+% \cs{text_purify_math_unchanged:n} \Arg{math}
+% \end{syntax}
+% Takes user input \meta{math} (which should be free of outer math mode
+% delimiters) and expresses it in the \meta{form}:
+% \begin{itemize}
+% \item \texttt{unchanged}: no manipulation at all, the tokens are
+% left delimited by the first pair in \cs{l_text_math_delims_tl}
+% (or if empty, a pair of |$|)
+% \item \textt{chars} Retains only the text characters (category code
+% $11$ and $12$) and spaces in the math mode material, and drops all
+% other content
+% \end{itemize}
+% In all cases, the result is protected from further expansion by
+% \cs{exp_not:n}.
+% \end{function}
+%
+% \begin{function}[added = 2019-12-08]{\text_set_purify_math_mode:n}
+% \begin{syntax}
+% \cs{text_set_purify_math_mode:n} \meta{mode}
+% \end{syntax}
+% Sets the math purification mode to one of \texttt{unchanged} or
+% \textt{chars}.
+% \end{function}
+%
% \begin{variable}{\l_text_accents_tl}
% Lists commands which represent accents, and which are left unchanged
% by expansion.
@@ -481,6 +512,14 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{macro}{\l_@@_math_mode_tl}
+% Used to control math mode output: internal as there is a dedicated
+% setter.
+% \begin{macrocode}
+\tl_new:N \l_@@_math_mode_tl
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Expansion to formatted text}
%
% \begin{variable}{\c_@@_chardef_space_token, \c_@@_mathchardef_space_token}
@@ -2252,10 +2291,14 @@
% \begin{macro}[rEXP]{\@@_purify_space:w}
% \begin{macro}[rEXP]{\@@_purify_N_type:N, \@@_purify_N_type_aux:N}
% \begin{macro}[rEXP]{\@@_purify_math_search:NNN}
-% \begin{macro}[rEXP]{\@@_purify_math_loop:Nw}
-% \begin{macro}[rEXP]{\@@_purify_math_N_type:NN}
-% \begin{macro}[rEXP]{\@@_purify_math_group:Nn}
-% \begin{macro}[rEXP]{\@@_purify_math_space:Nw}
+% \begin{macro}[rEXP]{\@@_purify_math_start:NNw}
+% \begin{macro}[rEXP]{\@@_purify_math_store:n}
+% \begin{macro}[rEXP]{\@@_purify_math_store:nw}
+% \begin{macro}[rEXP]{\@@_purify_math_end:w
+% \begin{macro}[rEXP]{\@@_purify_math_loop:NNw}
+% \begin{macro}[rEXP]{\@@_purify_math_N_type:NNN}
+% \begin{macro}[rEXP]{\@@_purify_math_group:NNn}
+% \begin{macro}[rEXP]{\@@_purify_math_space:NNw}
% \begin{macro}[rEXP]{\@@_purify_math_cmd:N}
% \begin{macro}[rEXP]{\@@_purify_math_cmd:NN}
% \begin{macro}[rEXP]{\@@_purify_math_cmd:Nn}
@@ -2322,42 +2365,59 @@
\token_if_eq_meaning:NNTF #1 #2
{
\use_i_delimit_by_q_recursion_stop:nw
- {
- \exp_not:n {#1}
- \@@_purify_math_loop:Nw #3
- }
+ { \@@_purify_math_start:NNw #2 #3 }
}
{ \@@_purify_math_search:NNN #1 }
}
-\cs_new:Npn \@@_purify_math_loop:Nw #1#2 \q_recursion_stop
+\cs_new:Npn \@@_purify_math_start:NNw #1#2#3 \q_recursion_stop
{
- \tl_if_head_is_N_type:nTF {#2}
- { \@@_purify_math_N_type:NN }
+ \@@_purify_math_loop:NNw #1#2#3 \q_recursion_stop
+ \@@_purify_math_result:n { }
+ }
+\cs_new:Npn \@@_purify_math_store:n #1
+ { \@@_purify_math_store:nw {#1} }
+\cs_new:Npn \@@_purify_math_store:nw #1#2 \@@_purify_math_result:n #3
+ { #2 \@@_purify_math_result:n { #3 #1 } }
+\cs_new:Npn \@@_purify_math_end:w #1 \@@_purify_math_result:n #2
+ {
+ \use:c { text_purify_math_ \l_@@_math_mode_tl :n } {#2}
+ \@@_purify_loop:w #1
+ }
+\cs_new:Npn \@@_purify_math_stop:Nw #1 \@@_purify_math_result:n #2
+ { \exp_not:n {#1#2} }
+\cs_new:Npn \@@_purify_math_loop:NNw #1#2#3 \q_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#3}
+ { \@@_purify_math_N_type:NNN }
{
- \tl_if_head_is_group:nTF {#2}
- { \@@_purify_math_group:Nn }
- { \@@_purify_math_space:Nw }
+ \tl_if_head_is_group:nTF {#3}
+ { \@@_purify_math_group:NNn }
+ { \@@_purify_math_space:NNw }
}
- #1#2 \q_recursion_stop
+ #1#2#3 \q_recursion_stop
}
-\cs_new:Npn \@@_purify_math_N_type:NN #1#2
+\cs_new:Npn \@@_purify_math_N_type:NNN #1#2#3
{
- \quark_if_recursion_tail_stop:N #2
- \exp_not:n {#2}
- \token_if_eq_meaning:NNTF #2 #1
- { \@@_purify_loop:w }
- { \@@_purify_math_loop:Nw #1 }
+ \quark_if_recursion_tail_stop_do:Nn #3
+ { \@@_purify_math_stop:Nw #1 }
+ \token_if_eq_meaning:NNTF #3 #2
+ { \@@_purify_math_end:w }
+ {
+ \@@_purify_math_store:n {#3}
+ \@@_purify_math_loop:NNw #1#2
+ }
}
-\cs_new:Npn \@@_purify_math_group:Nn #1#2
+\cs_new:Npn \@@_purify_math_group:NNn #1#2#3
{
- { \exp_not:n {#2} }
- \@@_purify_math_loop:Nw #1
+ \@@_purify_math_store:n { {#3} }
+ \@@_purify_math_loop:NNw #1#2
}
-\exp_after:wN \cs_new:Npn \exp_after:wN \@@_purify_math_space:Nw
- \exp_after:wN # \exp_after:wN 1 \c_space_tl
+\exp_after:wN \cs_new:Npn \exp_after:wN \@@_purify_math_space:NNw
+ \exp_after:wN # \exp_after:wN 1
+ \exp_after:wN # \exp_after:wN 2 \c_space_tl
{
- \c_space_tl
- \@@_purify_math_loop:Nw #1
+ \@@_purify_math_store:n { ~ }
+ \@@_purify_math_loop:NNw #1#2
}
% \end{macrocode}
% Then handle math mode as an argument: same outcomes, different input
@@ -2375,15 +2435,12 @@
\cs_if_eq:NNTF #2 #1
{
\use_i_delimit_by_q_recursion_stop:nw
- { \@@_purify_math_cmd:Nn #1 }
+ { \@@_purify_math_cmd:n }
}
{ \@@_purify_math_cmd:NN #1 }
}
-\cs_new:Npn \@@_purify_math_cmd:Nn #1#2
- {
- \exp_not:n { #1 {#2} }
- \@@_purify_loop:w
- }
+\cs_new:Npn \@@_purify_math_cmd:n #1
+ { \@@_purify_math_end:w \@@_purify_math_result:n {#1} }
% \end{macrocode}
% For \texttt{N}-type tokens, we first look for a string-context replacement
% before anything else: this can therefore cover anything. Assuming we don't
@@ -2447,6 +2504,10 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}
% {
@@ -2933,6 +2994,99 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Purifying math}
+%
+% \begin{macro}[rEXP]{\text_purify_math_unchanged:n}
+% \begin{macro}[rEXP]{\@@_purify_math_unchanged:Nw}
+% \begin{macro}[rEXP]{\@@_purify_math_unchanged:NNw}
+% Top-level functions for purifying math mode: just keep as-is.
+% \begin{macrocode}
+\cs_new:Npn \text_purify_math_unchanged:n #1
+ {
+ \exp_after:wN \@@_purify_math_unchanged:Nw
+ \l_text_math_delims_tl $ $ \q_stop
+ \exp_not:n {#1}
+ \exp_after:wN \@@_purify_math_unchanged:NNw
+ \l_text_math_delims_tl $ $ \q_stop
+ }
+\cs_new:Npn \@@_purify_math_unchanged:Nw #1#2 \q_stop
+ { \exp_not:n {#1} }
+\cs_new:Npn \@@_purify_math_unchanged:NNw #1#2#3 \q_stop
+ { \exp_not:n {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\text_purify_math_chars:n}
+% \begin{macro}[rEXP]{\@@_purify_math_chars_loop:w}
+% \begin{macro}[rEXP]{\@@_purify_math_chars_space:w}
+% \begin{macro}[rEXP]{\@@_purify_math_chars_group:n
+% \begin{macro}[rEXP]{\@@_purify_math_chars_N_type:N}
+% Just keeping the character text could be done using a faster loop,
+% but that looses the spaces. Not a big issue in math mode (thought it
+% is nice to keep them), but any nested text-in-math needs them: this
+% was there is no need to actually check for such material.
+% \begin{macrocode}
+\cs_new:Npn \text_purify_math_chars:n #1
+ {
+ \@@_purify_math_chars_loop:w #1
+ \q_recursion_tail \q_recursion_stop
+ }
+\cs_new:Npn \@@_purify_math_chars_loop:w #1 \q_recursion_stop
+ {
+ \tl_if_head_is_N_type:nTF {#1}
+ { \@@_purify_math_chars_N_type:N }
+ {
+ \tl_if_head_is_group:nTF {#1}
+ { \@@_purify_math_chars_group:n }
+ { \@@_purify_math_chars_space:w }
+ }
+ #1 \q_recursion_stop
+ }
+\exp_last_unbraced:NNo \cs_new:Npn \@@_purify_math_chars_space:w
+ \c_space_tl
+ {
+ \c_space_tl
+ \@@_purify_math_chars_loop:w
+ }
+\cs_new:Npn \@@_purify_math_chars_group:n #1
+ { \@@_purify_math_chars_loop:w #1 }
+\cs_new:Npn \@@_purify_math_chars_N_type:N #1
+ {
+ \quark_if_recursion_tail_stop:N #1
+ \bool_lazy_or:nnT
+ { \token_if_letter_p:N #1 }
+ { \token_if_other_p:N #1 }
+ { #1 }
+ \@@_purify_math_chars_loop:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\text_set_purify_math_mode:n}
+% Set up the mode for purification.
+% \begin{macrocode}
+\cs_new_protected:Npn \text_set_purify_math_mode:n #1
+ {
+ \cs_if_exist:cTF { text_purify_math_ #1:n }
+ { \tl_set:Nn \l_@@_math_mode_tl {#1} }
+ { \__kernel_msg_error:nnn { kernel } { unknown-purify-mode } {#1} }
+ }
+\text_set_purify_math_mode:n { unchanged }
+\__kernel_msg_new:nnnn { kernel } { unknown-purify-mode }
+ { Unknown~math_purification~mode~'#1'. }
+ {
+ LaTeX~knows~how~to~purify~math~mode~as~'unchanged',~
+ 'simple'~and~'unicode',~and~does~not~know~'#1'.
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/l3kernel/testfiles/m3text003.luatex.tlg b/l3kernel/testfiles/m3text003.luatex.tlg
index 165d69b57..afbb1475e 100644
--- a/l3kernel/testfiles/m3text003.luatex.tlg
+++ b/l3kernel/testfiles/m3text003.luatex.tlg
@@ -23,7 +23,7 @@ TEST 4: Math-mode escape
============================================================
Some text $y = \sin \theta $
Opps not close token in $y = \sin \theta
-\ensuremath {y=mx+c} is an equation
+$y=mx+c$ is an equation
============================================================
============================================================
TEST 5: Letter-like commands
diff --git a/l3kernel/testfiles/m3text003.ptex.tlg b/l3kernel/testfiles/m3text003.ptex.tlg
index f3efcb6c4..632ce1f8a 100644
--- a/l3kernel/testfiles/m3text003.ptex.tlg
+++ b/l3kernel/testfiles/m3text003.ptex.tlg
@@ -23,5 +23,5 @@ TEST 4: Math-mode escape
============================================================
Some text $y = \sin \theta $
Opps not close token in $y = \sin \theta
-\ensuremath {y=mx+c} is an equation
+$y=mx+c$ is an equation
============================================================
diff --git a/l3kernel/testfiles/m3text003.tlg b/l3kernel/testfiles/m3text003.tlg
index 509f3fd2d..a7bcec9b4 100644
--- a/l3kernel/testfiles/m3text003.tlg
+++ b/l3kernel/testfiles/m3text003.tlg
@@ -23,7 +23,7 @@ TEST 4: Math-mode escape
============================================================
Some text $y = \sin \theta $
Opps not close token in $y = \sin \theta
-\ensuremath {y=mx+c} is an equation
+$y=mx+c$ is an equation
============================================================
============================================================
TEST 5: Letter-like commands
diff --git a/l3kernel/testfiles/m3text003.uptex.tlg b/l3kernel/testfiles/m3text003.uptex.tlg
index 165d69b57..afbb1475e 100644
--- a/l3kernel/testfiles/m3text003.uptex.tlg
+++ b/l3kernel/testfiles/m3text003.uptex.tlg
@@ -23,7 +23,7 @@ TEST 4: Math-mode escape
============================================================
Some text $y = \sin \theta $
Opps not close token in $y = \sin \theta
-\ensuremath {y=mx+c} is an equation
+$y=mx+c$ is an equation
============================================================
============================================================
TEST 5: Letter-like commands
diff --git a/l3kernel/testfiles/m3text003.xetex.tlg b/l3kernel/testfiles/m3text003.xetex.tlg
index 165d69b57..afbb1475e 100644
--- a/l3kernel/testfiles/m3text003.xetex.tlg
+++ b/l3kernel/testfiles/m3text003.xetex.tlg
@@ -23,7 +23,7 @@ TEST 4: Math-mode escape
============================================================
Some text $y = \sin \theta $
Opps not close token in $y = \sin \theta
-\ensuremath {y=mx+c} is an equation
+$y=mx+c$ is an equation
============================================================
============================================================
TEST 5: Letter-like commands
More information about the latex3-commits
mailing list