在新命令中动态定义 sbox

在新命令中动态定义 sbox

我正在尝试使用图像名称作为输入参数来收集宏中任意数量图像的宽度。结果存储在全局数据工具列表中。不幸的是,结果列表始终包含之前添加的所有图像/字段添加到列表中的最后宽度。

此代码

\documentclass{article}
\usepackage{datatool}
\usepackage{graphicx}

\def\dimtomm #1{\the\numexpr \dimexpr #1\relax*635/118407168\relax }

\newsavebox\imagebox

\newcommand{\regimg}[2]{%
  \sbox{\imagebox}{\includegraphics[height=5cm]{#1}}
  \DTLnewrow{list}
  \DTLnewdbentry{list}{label}{#2}
  \DTLnewdbentry{list}{width}{\dimtomm{\wd\imagebox}}
}

\begin{document}
\DTLnewdb{list}

\regimg{img1.jpg}{1}
\regimg{img2.jpg}{2}
\regimg{img3.jpg}{3}

\DTLsort{width}{list}
\DTLforeach*{list}{\theLabel=label,\theWidth=width}{\theLabel - \theWidth\\}
\end{document}

产生以下输出:

1- 89
2- 89
2- 89

其中 89(mm)是最后一幅图像的宽度。之前的图像应该不同。

当我提取宏的代码并为每个图像使用不同的保存箱时,代码就可以工作了。所以问题是一些“范围问题”。我假设。我需要一些,或csname/expendafter构造\@nameuse。但无法弄清楚如何使用它们。globaletoolbox’ \csdef

我也尝试在宏中定义保存框动态,并在名称末尾加上一个运行数字,但也迷失了方向。非常欢迎任何朝着正确方向的推动。

答案1

您需要扩展\the\wd(而不是添加大量空间标记)

\newcommand{\regimg}[2]{%
  \sbox{\imagebox}{\includegraphics[height=5cm]{#1}}%%%
  \DTLnewrow{list}%%%
  \DTLnewdbentry{list}{label}{#2}%%%
  \edef\tmp{\noexpand\DTLnewdbentry{list}{width}{\noexpand\dimtomm{\the\wd\imagebox}}}%%%
  \tmp
}

答案2

刚刚发现这\dtlexpandnewvalue也会有技巧:

\newcommand{\regimg}[2]{%
  \sbox{\imagebox}{\includegraphics[height=5cm]{#1}}%
  \DTLnewrow{list}%
  \dtlexpandnewvalue%
  \DTLnewdbentry{list}{label}{#2}%
  \DTLnewdbentry{list}{width}{\dimtomm{\wd\imagebox}}%
}

答案3

您需要扩展该值,但不是以您所做的方式:\dtlexpandnewvalue是一个将“永远”保持的声明(使用通常的作用域规则)。

您还可以获得比四舍五入到毫米更精确的数字。

\documentclass{article}
\usepackage{datatool}
\usepackage{graphicx}
\usepackage{xfp}

%\newcommand\dimtomm[1]{\the\numexpr\dimexpr#1\relax*635/118407168\relax}
% this can show two exact decimal digits (or more)
\newcommand\dimtomm[1]{\fpeval{round(#1/(1mm),2)}}

\newsavebox\imagebox

\newcommand{\regimg}[2]{%
  \sbox{\imagebox}{\includegraphics[height=5cm]{#1}}%
  \DTLnewrow{list}%
  \DTLnewdbentry{list}{label}{#2}%
  \DTLnewdbentry{list}{width}{\dimtomm{\wd\imagebox}}%
}

\begin{document}
\DTLnewdb{list}

\dtlexpandnewvalue
\regimg{example-image.jpg}{1}
\regimg{example-image-9x16.jpg}{2}
\regimg{example-image-1x1.jpg}{3}
\dtlnoexpandnewvalue

\DTLsort{width}{list}

\DTLforeach*{list}{\theLabel=label,\theWidth=width}{\theLabel\ - \theWidth\par}

\end{document}

在此处输入图片描述

这就是您通过切换评论并使用您的定义所获得的结果。

在此处输入图片描述

或者,没有“expand”声明

\newcommand{\regimg}[2]{%
  \sbox{\imagebox}{\includegraphics[height=5cm]{#1}}%
  \DTLnewrow{list}%
  \DTLnewdbentry{list}{label}{#2}%
  \expanded{\noexpand\DTLnewdbentry{list}{width}{\dimtomm{\wd\imagebox}}}%
}

相关内容