在使用 `\expandafter` 时仍然有困难

在使用 `\expandafter` 时仍然有困难

首先,对于之前造成的任何混淆,我深感抱歉,我已将各种问题分成不同的页面。

这个问题是在尝试拆分十进制数时出现的。我的两个问题的好解决方案使用 pgf独立于软件包已经提供或即将在这些页面上提供。

这个问题的主要目的是我想更好地理解 LaTeX 中事物的扩展方式。下面的答案中就有关于这方面的有用信息。也许那些人不介意将题外话转移到上面链接的两个问题中,以帮助我简化情况。我意识到这有点棘手,因为扩展的想法是在分割长度的背景下讨论的。提前谢谢。

MWE 只是我正在尝试的一大堆想法,试图扩展值来得到我想要的东西,但失败了,因为我还不完全理解 LaTeX 或 TeX 如何扩展各种类型的值。

MWE 输出

MWE 输出

MWE 代码

\documentclass[12pt]{article}
\usepackage[a5paper,margin=14mm]{geometry}

\makeatletter
\def\printplainbefore#1{\expandafter\@printplainbefore#1..\@nil}
\def\@printplainbefore#1.#2.#3\@nil{#1}
\def\printplainafter#1{\expandafter\@printplainafter#1..\@nil}
\def\@printplainafter#1.#2.#3\@nil{#2}

\newcommand*{\getlength}[1]{\strip@pt#1}

\makeatother

\def\mythe#1{\expandafter\getlength{#1}}

\newcommand{\savenum}[2]{\expandafter\xdef\csname num#1\endcsname{#2}}
\newcommand{\getnum}[1]{\csname num#1\endcsname}

\newlength{\thislength}
\setlength{\thislength}{123.456pt}
\tracingmacros=1

\begin{document}
\par The: \the\thislength
    \quad Split: \printplainbefore{\the\thislength} -- \printplainafter{\the\thislength}
\par Getlength: \getlength{\thislength}
    \quad Split: \printplainbefore{\getlength{\thislength}} -- \printplainafter{\getlength{\thislength}}
\par MyThe: \mythe\thislength
    \quad Split: \printplainbefore{\mythe\thislength} -- \printplainafter{\mythe\thislength}
\par Getlength variable first: \getlength{\thislength}
    \quad Split: \xdef\test{\getlength{\thislength}} \printplainbefore{\test} -- \printplainafter{\test}
\par Getlength save: \getlength{\thislength}
    \quad Split: \savenum{thislength}{\getlength{\thislength}} \printplainbefore{\getnum{thislength}} -- \printplainafter{\getnum{thislength}}
\end{document}

答案1

我对你的代码有点困惑。但我看到几件事可能对你有帮助。

写作

\expandfater\getlength{#1}

效果等同于

\getlength{#1}

不带任何扩展。

如果#1你希望先扩展,那么你编写的代码不会这样做。相反,TeX{会尝试扩展。要实现这一点,#1你需要编写类似

\expandafter\getlength\expandafter{#1}

但这很可能也不会达到你想要的效果。如果#1是一串标记,例如如果你尝试

\def\a{ABC}
\def\b{\c}
\def\c{XYZ}
\def\mythe#1{\expandafter\getlength\expandafter{#1}}

然后

\mythe{\a\b\c}

扩展为

\expandafter\getlength\expandafter{\a\b\c}

然后扩展为

\getlength{ABC\b\c}

无法通过使用您所编写的来访问 of。现在,如果您知道应该\b\c只有一个标记,那么此时一切正常。#1\expandafter#1

如果想要获取维度的整数部分和小数部分,则下面的操作将实现该目的,而无需调用任何特殊包。

\documentclass{article}
\makeatletter

\def\getparts#1{%%
  \edef\my@stripped@length{\strip@pt#1}%%
  \expandafter\ae@int@frac\my@stripped@length..\@nil
}

\def\ae@int@frac#1.#2.#3\@nil{%%
  \def\aeinteger{#1}%%
  \def\aefraction{#2}%%
}

\newlength{\aetemp}
\setlength{\aetemp}{1.234cm}

\def\showparts{%%
  \begin{tabular}{ll}\hline
  Length   & \the\aetemp\\
  Integer  & \aeinteger \\
  Fraction & \aefraction\\\hline
  \end{tabular}}


\makeatother
\pagestyle{empty}
\begin{document}

\setlength{\aetemp}{1cm}
\getparts{\aetemp}
\showparts

\setlength{\aetemp}{215pt}
\getparts{\aetemp}
\showparts

\end{document}

在此处输入图片描述

答案2

问题是,\getlength需要几个扩展步骤才能结束其工作,提供一系列数字(中间有一个小数点)。我将在连续的行中显示它们

\getlength{\thislength}
\strip@pt\thislength
\expandafter\rem@pt\the\thislength
\[email protected]
123\ifnum 456>\z@ .456\fi
123.456

如果您希望看到它所期望的结果,则总共需要\expandafter执行 5 个扩展步骤,即 31 个标记,\@printplainbefore而不仅仅是一个标记。但是的存在\ifnum使得该宏在实践中无法使用。

由于您不想删除零小数部分,因此可以使用一个\romannumeral技巧:

\documentclass{article}

\makeatletter
\def\printplainbefore#1{\expandafter\@printplainbefore\romannumeral-`Q#1..\@nil}
\def\@printplainbefore#1.#2.#3\@nil{#1}
\def\printplainafter#1{\expandafter\@printplainafter\romannumeral-`Q#1..\@nil}
\def\@printplainafter#1.#2.#3\@nil{#2}

\begingroup\catcode`P=12 \catcode`T=12
\lowercase{\endgroup\def\simplerem@pt#1PT{#1}}
\def\simplestrip@pt{\expandafter\simplerem@pt\the}
\newcommand*{\getlength}[1]{\simplestrip@pt#1}

\makeatother

\newlength{\thislength}
\setlength{\thislength}{123.456pt}

\begin{document}
Number: 123.456
    \quad Split: \printplainbefore{123.456} -- \printplainafter{123.456}

\def\temp{123.456}
Macro: \texttt{\meaning\temp}
    \quad Split: \printplainbefore{\temp} -- \printplainafter{\temp}

The: \the\thislength
    \quad Split: \printplainbefore{\the\thislength} -- \printplainafter{\the\thislength}

Getlength: \getlength{\thislength}
    \quad Split: \printplainbefore{\getlength{\thislength}} -- \printplainafter{\getlength{\thislength}}

\end{document}

在此处输入图片描述

相关内容