首先,对于之前造成的任何混淆,我深感抱歉,我已将各种问题分成不同的页面。
这个问题是在尝试拆分十进制数时出现的。我的两个问题的好解决方案使用 pgf和独立于软件包已经提供或即将在这些页面上提供。
这个问题的主要目的是我想更好地理解 LaTeX 中事物的扩展方式。下面的答案中就有关于这方面的有用信息。也许那些人不介意将题外话转移到上面链接的两个问题中,以帮助我简化情况。我意识到这有点棘手,因为扩展的想法是在分割长度的背景下讨论的。提前谢谢。
MWE 只是我正在尝试的一大堆想法,试图扩展值来得到我想要的东西,但失败了,因为我还不完全理解 LaTeX 或 TeX 如何扩展各种类型的值。
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}