[latex3-commits] [git/LaTeX3-latex3-latex2e] gh239: Implement testing and copying \DeclareTextCommand-defined commands (e9eb7c0c)
PhelypeOleinik
tex.phelype at gmail.com
Thu Jun 4 03:15:37 CEST 2020
Repository : https://github.com/latex3/latex2e
On branch : gh239
Link : https://github.com/latex3/latex2e/commit/e9eb7c0c88af250d4da2e4cbfc43d012c9ae7928
>---------------------------------------------------------------
commit e9eb7c0c88af250d4da2e4cbfc43d012c9ae7928
Author: PhelypeOleinik <tex.phelype at gmail.com>
Date: Wed Jun 3 22:15:37 2020 -0300
Implement testing and copying \DeclareTextCommand-defined commands
>---------------------------------------------------------------
e9eb7c0c88af250d4da2e4cbfc43d012c9ae7928
base/ltoutenc.dtx | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 153 insertions(+)
diff --git a/base/ltoutenc.dtx b/base/ltoutenc.dtx
index b18a2ec3..23047885 100644
--- a/base/ltoutenc.dtx
+++ b/base/ltoutenc.dtx
@@ -1233,6 +1233,159 @@
% \end{macrocode}
% \end{macro}
%
+% \subsubsection{Copying font commands}
+%
+% \begin{macro}{\@if at DeclareTextCommand}
+% \begin{macro}{\@copy at DeclareTextCommand}
+% \begin{macro}{\@copy at declaretextcommand}
+% \begin{macro}{\@copy at declaretextcommand@enc}
+% \changes{v1.5h}{2020/05/09}{Added \cs{DeclareCommandCopy} (gh/239)}
+%
+% With the generic \cs{NewCommandCopy} macro defined earlier in
+% \texttt{ltdefns.dtx}, we can make a |\@if@|--|\@copy@| pair for
+% \cs{DeclareTextCommand}.
+%
+% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2020-10-01}{\@if at DeclareTextCommand}
+%<latexrelease> {Add \@if at DeclareTextCommand
+%<latexrelease> and \@copy at DeclareTextCommand}%
+%<*2ekernel|latexrelease>
+% \end{macrocode}
+%
+% Checking if a command is defined with \cs{DeclareTextCommand} is a
+% bit trickier than ones defined with \cs{DeclareRobustCommand}
+% because the \cs{meaning} of the defined command doesn't only depend
+% on the name of the command itself, but also on the default encoding
+% declared for the command. The \cs{meaning} of such a command
+% |\foo| defined with \cs{DeclareTextCommand} is:
+% |\<enc>-cmd \foo \<enc>\foo|. Without knowing what encoding |<enc>|
+% is we can't guess a definition for |\foo| and compare to check if
+% they are equal. The solution implemented here compares the
+% \cs{meaning} of the command with the template above, and if it fits,
+% then \cs{@if at DeclareTextCommand} will branch to true.
+% \begin{macrocode}
+\def\@if at DeclareTextCommand#1{%
+ \begingroup
+ \escapechar`\\
+% \end{macrocode}
+% We need to take extra care about control symbols like |\'|: their
+% meaning is something like \verb*=\?-cmd \'\?\' =, whereas control
+% words have a space after the second token: \verb*=\?-cmd \x \?\x =.
+% Here \cs{reserved at b} will expand to a space or to empty.
+% \begin{macrocode}
+ \edef\reserved at a{\string#1}%
+ \edef\reserved at b{\detokenize{#1}}%
+ \edef\reserved at b{\ifx\reserved at a\reserved at b\else\space\fi}%
+% \end{macrocode}
+% Here we start an exhaustive expansion of the rest of the macro.
+% \cs{reserved at a} is defined to have the template discussed above as
+% \meta{parameter text} and then match the \cs{meaning} of the command
+% being tested, and expand to \meta{true} or \meta{false} accordingly.
+% \begin{macrocode}
+ \begingroup\edef\x{\endgroup
+ \def\noexpand\reserved at a####1%
+ \detokenize{macro}:->%
+ \@backslashchar####2\detokenize{-cmd }%
+ \string#1\reserved at b
+ \@backslashchar####3\string#1 \noexpand\@nil
+ ####4\noexpand\@nnil\unexpanded{{%
+ \endgroup
+ \if x\ifx\relax##2y\fi
+ \ifx\relax##3y\fi x%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}}%
+% \end{macrocode}
+% Now just call \cs{reserved at a} with the \cs{meaning} of |#1| and with
+% a fallback text to match the definition of \cs{reserved at a}, but with
+% \cs{relax} in place of the encoding to signal that the function
+% should expand to false.
+% \begin{macrocode}
+ \noexpand\reserved at a
+ \meaning#1\noexpand\@nil
+ \detokenize{macro}:->%
+ \@backslashchar\relax\detokenize{-cmd }%
+ \string#1\reserved at b
+ \@backslashchar\relax\string#1 \noexpand\@nil
+ \noexpand\@nnil}%
+ \x}
+% \end{macrocode}
+%
+% Commands defined with \cs{DeclareTextCommand} have multiple possible
+% versions, depending on the encoding of the font used, and encoding
+% defaults declared for that command. To make sure we catch all
+% possibilities, we list all encodings loaded by the \LaTeXe{} kernel
+% by default, and extend it with \cs{@fontenc at load@list}:
+% \begin{macrocode}
+\def\@loaded at encoding@list{OML,OMS,TS1}
+% \end{macrocode}
+%
+% To copy a command here, start by expanding (in a group) the list of
+% loaded encodings, and then |x|-expand:
+% \begin{macrocode}
+\def\@copy at DeclareTextCommand#1#2{%
+ \begingroup
+ \escapechar=`\\
+ \edef\@loaded at encoding@list{\@loaded at encoding@list,%
+ \expandafter\@secondoftwo\@fontenc at load@list}%
+ \edef\x{\endgroup
+% \end{macrocode}
+%
+% Here we define the top-level macro |#1| as:
+% \verb*=\<enc>-cmd #1 \<enc>\#1=, using
+% \cs{@copy at declaretextcommand@enc} to take the name of the default
+% encoding from the command being copied (|#2|):
+% \begin{macrocode}
+ \def\noexpand#1{%
+ \expandafter\noexpand\csname
+ \expandafter\@copy at declaretextcommand@enc
+ \meaning#2\@nil-cmd\endcsname
+ \noexpand#1%
+ \expandafter\noexpand\csname
+ \expandafter\@copy at declaretextcommand@enc
+ \meaning#2\@nil\string#1\endcsname}%
+% \end{macrocode}
+%
+% Finally, call \cs{@copy at declaretextcommand} in a loop to copy
+% |\<enc>\#2| into |\<enc>\#1| for every \meta{enc} in
+% \cs{@loaded at encoding@list}:
+% \begin{macrocode}
+ \noexpand\@for\noexpand\@elt:=\@loaded at encoding@list\noexpand\do
+ {\unexpanded{%
+ \expandafter\@copy at declaretextcommand\expandafter{\@elt}}%
+ {\@expl at cs@to at str@@N#1}{\@expl at cs@to at str@@N#2}%
+ }%
+ }\x}
+% \end{macrocode}
+%
+% Now \cs{@copy at declaretextcommand} just checks if |\<enc>\#2| exists,
+% and then copies it:
+% \begin{macrocode}
+\def\@copy at declaretextcommand#1#2#3{%
+ \@ifundefined{#1\@backslashchar#3}{}{%
+ \expandafter\declare at command@copy at let
+ \csname#1\@backslashchar#2\expandafter\endcsname
+ \csname#1\@backslashchar#3\endcsname}}
+% \end{macrocode}
+%
+% Now the rollback code.
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000-00-00}{\@if at DeclareTextCommand}
+%<latexrelease> {Undefine \@if at DeclareTextCommand
+%<latexrelease> and \@copy at DeclareTextCommand}%
+%<latexrelease>\let\@if at DeclareTextCommand\@undefined
+%<latexrelease>\let\@copy at DeclareTextCommand\@undefined
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \subsubsection{Hyphenation}
%
More information about the latex3-commits
mailing list.