缠绕长度

缠绕长度

我拼凑了一个\basis宏,它设置并获取隐藏/内部长度\b@sis。它的工作原理如下:

  1. 调用\basis返回值\b@sis
  2. 调用\basis{}设置\b@sis为默认值(当前字体大小\f@size)并
  3. 调用\basis{1ex}将设置\b@sis为指定的长度。

\basis2 和 3 有效,但 1 并不总是按预期返回值。例如,我无法在 TikZ 中用作长度,也无法使用\the\basis或显示其值\showthe\basis。我还尝试\expandafter在前两个“the”命令前添加前缀,但没有效果。以下是我目前的代码

\documentclass{standalone}
\usepackage{luatex85}

\usepackage{xparse}
\usepackage{ifthen}
\usepackage{xifthen}
\usepackage{tikz}
\usepackage{booktabs}

\makeatletter
\newlength{\b@sis}
\newlength{\length}
\setlength{\length}{2pt}
\setlength{\b@sis}{2pt}
\ProvideDocumentCommand{\basis}{g}{%
 \IfNoValueTF{#1}{%
  \b@sis}{%
  \ifthenelse{\isempty{#1}}%
  {\setlength{\b@sis}{\f@size pt}%
   \setlength{\length}{\f@size pt}}%
  {\setlength{\b@sis}{#1}%
   \setlength{\length}{#1}}}}%
\newcommand{\showbasis}{\the\b@sis}
\makeatother

\begin{document}
\begin{tabular}{|l|r|c|c|}                                                   % The following calls fail
\toprule
No response  & \basis        \showbasis & \tikz \draw circle(0.5*\length);            \\%& \tikz \draw circle(0.5*\basis); \\
\midrule
Sets default & \basis{}      \showbasis & \basis{}\tikz \draw circle(0.5*\length);    \\%& \tikz \draw circle(0.5*\basis); \\
\midrule
Sets Value   & \basis{1ex}   \showbasis & \basis{1ex}\tikz \draw circle(0.5*\length); \\%& \tikz \draw circle(0.5*\basis); \\
\bottomrule
\end{tabular}
\end{document}

其输出如下所示

在此处输入图片描述

我认为,\IfNoValueTF当没有参数时,就不会扩展,也不会返回预期的长度。是否有某种方法可以扩展它以返回内部长度,或者是否有更好的方法来实现这一点。

我看到\ProvideDocumentCommand允许一个l论点,也许我应该在我的定义中使用它?例如,是否有变化\basis正在提前读取第一个非空白字符,xparse手册暗示可能是这种情况。

更新

Egreg 显然有更好的解决方案,但我是在 David Carlisle 回应之后才看到它,而且我又对其进行了一些调整。我必须使用界面\basis\basis[VALUE]设置值并\basis*检索它。但这确实是一种糟糕的做法,当然不是什么星星代表什么

\ProvideDocumentCommand{\basis}{s o}{%
 \IfBooleanTF{#1}
  {\the\b@sis}
  {\IfNoValueTF{#2}{%
    \setlength{\b@sis}{\f@size pt}%
    \setlength{\length}{\f@size pt}}
   {\setlength{\b@sis}{#2}%
    \setlength{\length}{#2}}}
  }%

答案1

使用可选参数定义的命令g是不可扩展的,因此不能\basis在扩展上下文中使用不带参数的命令,例如

\draw circle(0.5*\basis)

按照建议,最好将调用分为设置变量和使用变量。您可以充分利用 的功能expl3来获得更高效的代码。

\documentclass[border=4pt]{standalone}
\usepackage{luatex85}

\usepackage{xparse}
\usepackage{tikz}
\usepackage{booktabs}

\ExplSyntaxOn
\dim_new:N \l_carel_basis_dim
\dim_set:Nn \l_carel_basis_dim { 2pt }

\NewDocumentCommand{\setbasis}{O{\use:c {f@size} pt}}
 {
  \dim_set:Nn \l_carel_basis_dim { #1 }
 }

\NewExpandableDocumentCommand{\basis}{}{\dim_use:N \l_carel_basis_dim}
\ExplSyntaxOff

\begin{document}
\begin{tabular}{lrcc}
\toprule
Initial value & \basis & \tikz \draw circle(0.5*\basis); \\
\midrule
Sets default & \setbasis\basis & \setbasis\tikz \draw circle(0.5*\basis); \\
\midrule
Sets Value   & \setbasis[1ex]\basis & \setbasis[1ex]\tikz \draw circle(0.5*\basis); \\
\bottomrule
\end{tabular}
\end{document}

在此处输入图片描述

答案2

发布的代码运行时没有错误并且产生了我所期望的结果,但是您没有说出您期望它做什么。

使用相同命令来设置和检索的用户界面非常令人困惑,也许这就是混乱的根源。

在第二行和第三行的第二列中,你设置了长度,但在第一行中,你有一个相当奇怪的构造

\basis        \showbasis

\basis扩展到内部长度的使用并\showbasis 扩展到\the应用于该长度。

如果你把它改成

\basis        \showbasis\showbasis 

因此如果\b@sis最初设置为 2pt,那么

\basis        \showbasis

\b@sis        \the\b@sis

扩展为

 \b@sis 2pt

因此设置\b@sis为其已有的值 2pt。

像我一样添加第二个,\showbasis将 2pt 打印到表格中,

在此处输入图片描述

然后您会看到该值为 2pt,因此圆圈很小。

如果您只\basis在单元格上单独放置一个单元格,那么您会得到一个缺失数字错误,因为它是一个长度的分配,而没有提供值。

相关内容