[latex3-commits] [git/LaTeX3-latex3-latex2e] everymath: Initial proposal for math capture (d38206d7)

Joseph Wright joseph.wright at morningstar2.co.uk
Fri Dec 9 12:31:59 CET 2022


Repository : https://github.com/latex3/latex2e
On branch  : everymath
Link       : https://github.com/latex3/latex2e/commit/d38206d79ee1e1d4b2e633c60695023112fe79cc

>---------------------------------------------------------------

commit d38206d79ee1e1d4b2e633c60695023112fe79cc
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Fri Dec 9 11:31:59 2022 +0000

    Initial proposal for math capture


>---------------------------------------------------------------

d38206d79ee1e1d4b2e633c60695023112fe79cc
 required/latex-lab/changes.txt                     |   5 +
 required/latex-lab/latex-lab-everymath.dtx         | 347 +++++++++++++++++++++
 required/latex-lab/latex-lab.ins                   |   1 +
 required/latex-lab/testfiles/everymath-001.lvt     |  47 +++
 .../latex-lab/testfiles/everymath-001.tlg          |   6 +-
 5 files changed, 404 insertions(+), 2 deletions(-)

diff --git a/required/latex-lab/changes.txt b/required/latex-lab/changes.txt
index b4b4df98..5852afe9 100644
--- a/required/latex-lab/changes.txt
+++ b/required/latex-lab/changes.txt
@@ -1,3 +1,8 @@
+2022-12-09 Joseph Wright <Joseph.Wright at latex-project.org>
+
+	* latex-lab-everymath.dtx
+	 New file to implement grabbing of math mode context
+
 2022-07-22  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
 
 	* latex-lab-footnotes.dtx (subsection{Document-level commands}):
diff --git a/required/latex-lab/latex-lab-everymath.dtx b/required/latex-lab/latex-lab-everymath.dtx
new file mode 100644
index 00000000..e30afa61
--- /dev/null
+++ b/required/latex-lab/latex-lab-everymath.dtx
@@ -0,0 +1,347 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-everymath.dtx
+% Copyright (C) 2022 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
+%
+%
+% The development version of the bundle can be found below
+%
+%    https://github.com/latex3/latex2e/required/latex-lab
+%
+% for those people who are interested or want to report an issue.
+%
+%<*driver>
+\documentclass{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+  \DocInput{latex-lab-everymath.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+%
+% \title{The \texttt{latex-lab-everymath} code\thanks{}}
+% \author{\LaTeX{} Project}
+%
+% \maketitle
+%
+% \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}}
+% \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}}
+% \providecommand\class[1]{\texttt{#1.cls}}
+% \providecommand\pkg[1]{\texttt{#1}}
+% \providecommand\hook[1]{\texttt{#1}}
+%
+% \begin{abstract}
+% \end{abstract}
+%
+% \tableofcontents
+%
+% This file implements capture of all math mode material at the top level.
+% It provides one code-level interface to use this captured input.
+%
+% \begin{function}{\math_processor:n}
+%   \begin{syntax}
+%     \cs{math_processor:n} \Arg{tokens}
+%   \end{syntax}
+%   Declares that the captured math content should be passed to the
+%   \meta{tokens}, which will receive the content as |#1|.
+% \end{function}
+%
+% \MaybeStop{\setlength\IndexMin{200pt}  \PrintIndex  }
+%
+% \section{The Implementation}
+%
+%    \begin{macrocode}
+%<@@=math>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*kernel>
+%    \end{macrocode}
+%
+% \subsection{File declaration}
+%    \begin{macrocode}
+\ProvidesFile{latex-lab-everymath.ltx}
+        [2022-12-09 v0.1a Grab all the math(s)]
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\ExplSyntaxOn
+%    \end{macrocode}
+%
+% \subsection{Setup}
+%
+% Loading \pkg{amsmath} is an absolute requirement: this avoids needing to
+% have conditional definitions and deals with how to define \cs{[}/\cs{]}
+% neatly.
+%    \begin{macrocode}
+\AddToHook { begindocument / before }
+  { \RequirePackage { amsmath } }
+%    \end{macrocode} 
+%
+% \subsection{Data structures}
+%
+% \begin{variable}{\l_@@_cmd_bool}
+%   Tracks whether we are dealing with \LaTeX{}'s math mode (which is
+%   referred to here as \texttt{cmd}).
+%    \begin{macrocode}
+\bool_new:N \l_@@_cmd_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_inner_bool}
+%   Tracks if we are inside a top-level inline math context.
+%    \begin{macrocode}
+\bool_new:N \l_@@_inner_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_display_bool}
+%   Tracks display style (cases where \cs{everydisplay} is triggered).
+%    \begin{macrocode}
+\bool_new:N \l_@@_display_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_env_bool}
+%   Tracks math environments which deal with grabbing themselves.
+%    \begin{macrocode}
+\bool_new:N \l_@@_env_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \subsection{Interface commands}
+%
+% \begin{macro}{\@@_process:n, \@@_process_aux:n}
+%   A no-op place-holder; the internal wrapper means that it does not need to
+%   be concerned with internals.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_process:n #1
+  {
+    \legacy_if:nF { measuring@ }
+      { \@@_process_aux:n {#1} }
+  }
+\cs_new_protected:Npn \@@_process_aux:n #1 { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\math_processor:n}
+%   A simple installer
+%    \begin{macrocode}
+\cs_new_protected:Npn \math_processor:n #1
+  { \cs_set_protected:Npn \@@_process_aux:n ##1 {#1} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Content grabbing}
+%
+% \begin{macro}{\@@_grab_inline_dollar:w}
+%   Grab up to a single |$|, for inline math mode.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_inline_dollar:w % $
+  #1 $
+  {
+    \@@_process:n {#1} % $
+    #1 $
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_grab_inline_cmd:w}
+%   The same but for the \LaTeX{} structure.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_inline_cmd:w % \(
+  #1 \)
+  {
+    \@@_process:n {#1} % \(
+    #1 \)
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_dollardollar:w}
+%   And for the classical \TeX{} display structure.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_dollardollar:w % $$
+  #1 $$
+  {
+    \@@_process:n {#1} % $$
+    #1 $$
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Document commands}
+%
+% \begin{macro}{\(, \)}
+%   Here, we need to add the boolean around the structure; we also need to
+%   ensure that the conditional is finished before the |$| activates. To do
+%   that, we switch to an \pkg{expl3} structure for ease. There's no downside
+%   here to engine-protected, so we also simplify the setup a little.
+%    \begin{macrocode}
+\cs_gset_protected:Npn \( % \)
+  {
+    \bool_set_true:N \l_@@_cmd_bool
+    \mode_if_math:TF
+      { \@badmath }
+      { $ }
+  } % \(
+\cs_gset_protected:Npn \) %
+  {
+    \mode_if_math:TF
+      { $ }
+      { \@badmath }
+    \bool_set_false:N \l_@@_cmd_bool
+  }
+\cs_undefine:c { ( \c_space_tl }
+\cs_undefine:c { ) \c_space_tl }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {\equation, \@@_equation_begin:, \equation*, \@@_equation_star_begin:}
+% \begin{macro}
+%   {\endequation, \@@_equation_end:, \endequation*, \@@_equation_star_end:}
+%   These environments are not set up by \pkg{amsmath} to collect their body,
+%   so we do that here. This has to be done \emph{after} we can be sure
+%   \pkg{amsmath} is loaded.
+%    \begin{macrocode}
+\AddToHook { begindocument }
+  {
+    \cs_new_eq:NN \@@_equation_begin: \equation
+    \cs_new_eq:NN \@@_equation_end: \endequation
+    \RenewDocumentEnvironment { equation } { b }
+      {
+        \bool_set_true:N \l_@@_env_bool
+        \@@_process:n {#1}
+        \@@_equation_begin: #1 \@@_equation_end:
+      }
+      { }
+    \cs_new_eq:Nc \@@_equation_star_begin: { equation* }
+    \cs_new_eq:Nc \@@_equation_star_end: { endequation* }
+    \RenewDocumentEnvironment { equation* } { b }
+      {
+    \bool_set_true:N \l_@@_env_bool
+        \@@_process:n {#1}
+        \@@_equation_star_begin: #1 \@@_equation_star_end:
+      }
+      { }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\[, \]}
+%   A slight oddity: we have to collect the body but want to pass on
+%   to the more formal structure. That means that \cs{]} is no longer
+%   a command, but rather a marker. Again, we need to watch for when
+%   \pkg{amsmath} is loaded after this code.
+%    \begin{macrocode}
+\AddToHook { begindocument }
+  {
+    \cs_gset_protected:Npn \[ #1 \]
+      {
+        \begin{ equation* } #1 \end { equation* }
+      } % \[
+    \cs_gset_protected:Npn \] { }
+    \cs_undefine:c { [ \c_space_tl }
+    \cs_undefine:c { ] \c_space_tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{\cs{everymath} and \cs{everydisplay}}
+%
+% The business end for grabbing inline math and \enquote{raw} \TeX{}
+% display. Most display math mode is actually handled elsewhere, as we
+% have macro control.
+%    \begin{macrocode}
+\exp_args:No \tex_everymath:D
+  {
+    \tex_the:D \tex_everymath:D
+    \bool_lazy_or:nnF
+      { \l_@@_inner_bool }
+      { \l_@@_display_bool }
+      {
+        \bool_set_true:N \l_@@_inner_bool
+        \bool_if:NTF \l_@@_cmd_bool
+          { \@@_grab_inline_cmd:w }
+          { \@@_grab_inline_dollar:w }
+      }
+  }
+\exp_args:No \tex_everydisplay:D
+  {
+    \tex_the:D \tex_everydisplay:D
+    \bool_set_true:N \l_@@_display_bool
+    \bool_if:NF \l_@@_env_bool
+      { \@@_grab_dollardollar:w }
+  }
+%    \end{macrocode}
+%
+% \subsection{Modifying environments and \pkg{amsmath}}
+%
+% Mark up all of the display environments as the content is captured anyway.
+%    \begin{macrocode}
+\clist_map_inline:nn
+  { align , aligned , gather , gathered }
+  {
+    \AddToHook{ env / #1 / begin }
+      { \bool_set_true:N \l_@@_env_bool }
+    \AddToHook{ env / #1* / begin }
+      { \bool_set_true:N \l_@@_env_bool }
+  }
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_measure@:n}
+% \begin{macro}{\measure@}
+%   The \pkg{amsmath} environments use a common internal command that is a
+%   useful place to pick up the content.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_measure@:n \measure@
+\cs_gset_protected:Npn \measure@ #1
+  {
+    \@@_process:n {#1}
+    \@@_measure@:n {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\textdef@}
+%   To deal with \cs{text}, we directly re-define as the resets need to be
+%   inside a group.
+%    \begin{macrocode}
+\cs_gset_protected:Npn \textdef@ #1#2#3
+  {
+    \hbox
+      {
+        {
+          \bool_set_true:N \l_@@_cmd_bool
+          \bool_set_false:N \l_@@_display_bool
+          \everymath {#1}
+          \let \f at size #2
+          \selectfont #3
+        }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\ExplSyntaxOff
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%</kernel>
+%    \end{macrocode}
+%
+% \Finale
+%
diff --git a/required/latex-lab/latex-lab.ins b/required/latex-lab/latex-lab.ins
index bc668a71..17213e5d 100644
--- a/required/latex-lab/latex-lab.ins
+++ b/required/latex-lab/latex-lab.ins
@@ -77,6 +77,7 @@ where one can also log issues in case there are any.
 \generate{\file{latex-lab-testphase-new-or.sty}{\from{latex-lab-new-or.dtx}{code}}}
 \generate{\file{latex-lab-footmisc.ltx}{\from{latex-lab-footnotes.dtx}{footmisc}}}
 \generate{\file{latex-lab-footnotes.ltx}{\from{latex-lab-footnotes.dtx}{kernel}}}
+\generate{\file{latex-lab-everymath.ltx}{\from{latex-lab-everymath.dtx}{kernel}}}
 
 
 \endbatchfile
diff --git a/required/latex-lab/testfiles/everymath-001.lvt b/required/latex-lab/testfiles/everymath-001.lvt
new file mode 100644
index 00000000..f6b3b3bd
--- /dev/null
+++ b/required/latex-lab/testfiles/everymath-001.lvt
@@ -0,0 +1,47 @@
+\DocumentMetadata{testphase=phase-II}
+
+\documentclass{article}
+
+\input{regression-test}
+
+\RequirePackage[enable-debug ,check-declarations]{expl3}
+\ExplSyntaxOn
+\debug_on:n { deprecation }
+\ExplSyntaxOff
+
+\makeatletter
+\input{latex-lab-everymath.ltx}
+\makeatother
+\ExplSyntaxOn
+\math_processor:n
+  {
+    \TIMO
+    \TYPE {#1}
+    \OMIT
+  }
+\ExplSyntaxOff
+
+\begin{document}
+
+\START
+\OMIT
+
+Is
+$$ y = mx + c$$
+or
+\begin{equation}
+y = mx + c
+\end{equation}
+or 
+\[y = mx + c \quad \hbox{for all $c$}\]
+cool?
+
+So
+\begin{align}
+  a + b &= c \\
+  d + e &= f \\
+\end{align}
+
+Try $g_{\hbox{foo$b$}}$
+
+\END
diff --git a/base/testfiles-lthooks/github-0464.tlg b/required/latex-lab/testfiles/everymath-001.tlg
similarity index 52%
copy from base/testfiles-lthooks/github-0464.tlg
copy to required/latex-lab/testfiles/everymath-001.tlg
index fd6372fe..d72ca80a 100644
--- a/base/testfiles-lthooks/github-0464.tlg
+++ b/required/latex-lab/testfiles/everymath-001.tlg
@@ -1,4 +1,6 @@
 This is a generated file for the l3build validation system.
 Don't change this file in any respect.
-(testA.tex)
-After "testA.tex"
+ y = mx + c
+y = mx + c
+y = mx + c \hskip 1em\relax \hbox {for all $c$}
+g_{\hbox {foo$b$}}





More information about the latex3-commits mailing list.