命令的评估会改变其价值吗?

命令的评估会改变其价值吗?

我正在尝试使用 pgf-umlcd 创建 UML 类图,但遇到了问题。最终,我想使用指定的水平间距。我还需要能够设置文本宽度

我希望能够处理不同的锚点。我的计算应该没问题,但是命令似乎被评估为不同的值。

我创建了一个包含两个类的示例。一个类使用“变量”,另一个类使用其值。

重现代码:

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} 
\usepackage{tikz}
\usepackage{pgf-umlcd}

\begin{document}
    \begin{tikzpicture}[font=\small,outer frame sep=0,outer sep=0]
    \newcommand{\currTextWidth}{7.5cm}
    \newcommand{\desiredSpacing}{0cm}

    \newcommand{\pad}{\the\dimexpr \pgfkeysvalueof{/pgf/inner xsep}*2\relax} % calculate padding
    
    \newcommand{\overAllWidth}{\the\dimexpr \currTextWidth + (\pad)\relax}
    \newcommand{\currSpacing}{\the\dimexpr \desiredSpacing + \overAllWidth / 2\relax}

    % this resembles the referenced class
    \begin{class}[text width=\currTextWidth]{RandomClass}{0,0}
       \operation[0]{+ doSomething(): void}
    \end{class}

    % calculated values
    \node at (0,1.5)  {overAllWidth = \overAllWidth};
    \node at (0,1)  {currSpacing = \currSpacing};

    % this result would be fine
    \begin{class}[text width=\currTextWidth,right=109.78008pt]{ClassUsingValue}{RandomClass.north}
    \end{class}

    % but I want to use the 'variable' here
    \begin{class}[text width=\currTextWidth,right=\currSpacing]{ClassUsingVariable}{RandomClass.south}
    \end{class}
\end{tikzpicture}
\end{document}

输出:

变量评估 ev

答案1

至少对我来说,在这里使用\newcommand而不是 并没有多大意义。为什么不使用 LaTeX 长度,而要将 LaTeX 宏转换为尺寸?\newlength

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc} 
\usepackage{tikz}
\usepackage{pgf-umlcd,calc}
\newlength\desiredSpacing
\newlength\currTextWidth
\newlength\pad
\newlength\overAllWidth
\newlength\currSpacing

\begin{document}
\begin{tikzpicture}[font=\small,outer frame sep=0,outer sep=0]
  \setlength\desiredSpacing{0cm}
  \setlength\currTextWidth{7.5cm}
  \setlength\pad{\pgfkeysvalueof{/pgf/inner xsep}*2}
  \setlength\overAllWidth{\currTextWidth + \pad}
  \setlength\currSpacing{\desiredSpacing + \overAllWidth / 2}
  
  % this resembles the referenced class
  \begin{class}[text width=\currTextWidth]{RandomClass}{0,0}
    \operation[0]{+ doSomething(): void}
  \end{class}
  
  % calculated values
  \node at (0,1.5)  {overAllWidth = \the\overAllWidth};
  \node at (0,1)  {currSpacing = \the\currSpacing};
  
  % this result would be fine
  \begin{class}[text width=\currTextWidth,right=109.78008pt]{ClassUsingValue}{RandomClass.north}
  \end{class}
  
  % but I want to use the 'variable' here
  \begin{class}[text width=\currTextWidth,right=\currSpacing]{ClassUsingVariable}{RandomClass.south}
  \end{class}
\end{tikzpicture}
\end{document}

对齐结果

答案2

问题是,当你在里面时,class的值inner xsep为零,但是当你在中排版文本时情况就不同了\node

如果我添加

\showthe\dimexpr\pgfkeysvalueof{/pgf/inner xsep}\relax

class环境中,我得到了0.0pt,但是当我将它添加到节点内部时,我得到了3.08224pt

如果要冻结 的值inner xsep,则需要\edef而不是\newcommand(与 相同\def)。

\documentclass{article}
\usepackage{tikz}
\usepackage{pgf-umlcd}

\begin{document}

\begin{tikzpicture}[font=\small,outer frame sep=0,outer sep=0]
\def\currTextWidth{7.5cm}
\def\desiredSpacing{0cm}
\edef\pad{\the\dimexpr \pgfkeysvalueof{/pgf/inner xsep}*2\relax} % calculate padding
\edef\overAllWidth{\the\dimexpr \currTextWidth + (\pad)\relax}
\edef\currSpacing{\the\dimexpr \desiredSpacing + \overAllWidth / 2\relax}
% this resembles the referenced class
\begin{class}[text width=\currTextWidth]{RandomClass}{0,0}
   \operation[0]{+ doSomething(): void}
\end{class}
% calculated values
\node at (0,1.5)  {overAllWidth = \overAllWidth};
\node at (0,1)  {currSpacing = \currSpacing};
% this result would be fine
\begin{class}[text width=\currTextWidth,right=106.69783pt]{ClassUsingValue}{RandomClass.north}
\end{class}
% but I want to use the 'variable' here
\begin{class}[text width=\currTextWidth,right=\currSpacing]{ClassUsingVariable}{RandomClass.south}
\end{class}
\end{tikzpicture}

\end{document}

在命名此类命令时要小心,因为\def\edef会默默地(本地)改变现有命令的含义。

但为了安全起见,您仍然可以使用\newcommand

\begin{tikzpicture}[font=\small,outer frame sep=0,outer sep=0]
\newcommand{\currTextWidth}{7.5cm}
\newcommand{\desiredSpacing}{0cm}
\ExpandArgs{ne}\newcommand{\pad}{\the\dimexpr \pgfkeysvalueof{/pgf/inner xsep}*2\relax}
\ExpandArgs{ne}\newcommand{\overAllWidth}{\the\dimexpr \currTextWidth + (\pad)\relax}
\ExpandArgs{ne}\newcommand{\currSpacing}{\the\dimexpr \desiredSpacing + \overAllWidth / 2\relax}
% this resembles the referenced class
[...]

因为\ExpandArgs默认跳过其参数后面的标记;ne我们指示对后面的第一个大括号组不执行任何操作,并完全展开后面的第二个大括号组的内容。

在此处输入图片描述

相关内容