用复杂内容填充 tikz 矩阵

用复杂内容填充 tikz 矩阵

我正在尝试使用循环列表参数来tikz matrix动态填充,并使用操作将其进一步分解。foreachxstring

我遇到了一个问题,据我所知,生成的临时宏\StrBefore在宏链中丢失/无法读取。

编译器告诉我icons/.png找不到该文件 - 据我所知(和 LaTeX 术语),这归结为宏扩展不起作用:

LaTeX Warning: File `icons/.png' not found on input line 63.

! Unable to load picture or PDF file 'icons/.png'.
<to be read again> 
                   }
l.63 ...{(0,0)}{Fish}{1}{Farmers:800,Workers:1200}

此外,我收到一个实际错误,提示我未定义控制序列。这是由以下代码生成的临时宏\StrBefore

! Undefined control sequence.
<recently read> \templeft 

l.63 ...{(0,0)}{Fish}{1}{Farmers:800,Workers:1200}

以下是 MWE:

\documentclass{article}

\usepackage{calc}
\usepackage{geometry}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{xstring}

% PAGE GEOMETRY
\geometry{a4paper,
          landscape,
          top=1cm,
          bottom=1cm,
          left=1cm,
          right=1cm,
          includehead,
          includefoot}
\usetikzlibrary{calc, matrix}
% END PAGE GEOMETRY

% META

% sizes
\newcommand{\unitsize}{1cm}

% #1 > (x,y)
% #2 > Object_Name (filename without .png)
% #3 Amount
% #4 > Comma Separated list: <stratum>:<amount>,<stratum>:<amount>, ...
% >{\SplitList{,}}
\NewDocumentCommand{\consnode}{m m m m}{
    \node (#2) at #1 {
        \let\matrixcontents\empty
        \foreach \c in {#4}{
            \StrBefore{\c}{:}[\templeft]
            \StrBehind{\c}{:}[\tempright]

            \expandafter\gappto\expandafter\matrixcontents{\expandafter\consimg{\expandafter\templeft} \&}
            \expandafter\gappto\expandafter\matrixcontents\expandafter{\tempright \\}
        }

        \begin{tikzpicture}
            \node[label={[label distance=-(0.35*\unitsize)]105:#3×}] at (0,0) {
                \includegraphics[width=\unitsize, height=\unitsize]{icons/#2}};
            \matrix[row sep=-2mm, matrix of nodes, ampersand replacement=\&] (output) at (0,-1) {
                \matrixcontents
                %\includegraphics[width=\unitsize/2, height=\unitsize/2]{icons/example-image-b.png} \& 800 \\
                %\includegraphics[width=\unitsize/2, height=\unitsize/2]{icons/example-image-c.png} \& 1200 \\
                };
        \end{tikzpicture}};
}

\newcommand{\consimg}[1]{
    \includegraphics[width=\unitsize/2, height=\unitsize/2]{icons/#1.png}
}

% END META

\begin{document}

\begin{tikzpicture}
    \consnode{(0,0)}{example-image-a}{1}{example-image-b:800,example-image-c:1200}
\end{tikzpicture}

\end{document}

(矩阵定义中注释掉的部分产生了所需的输出,另见下面的图像,这就是我想要替换的内容
!请注意,我按照注释中的建议用示例名称替换了图像名称,我的命令中的图像名称兼作 tikz 节点的标识符名称)


这是我想要实现的预期结果(我通过对矩阵进行硬编码实现了):一条鱼的图形位于两个代表不同民族风格的图标下方,每个图标旁边都有数字 800


我正在使用 Overleaf(使用 XeLaTeX 编译),并且希望继续使用它。

我在各种文档的帮助下拼凑了代码,但在这种情况下主要有以下两个问题:

Tikz foreach 矩阵内部

Tikz 矩阵内部使用命令进行 Foreach 循环

答案1

正如发布的第一个错误是

! LaTeX Error: File `icons/example-image-a' not found.

我删掉了icons/

然后你得到

! Undefined control sequence.
<recently read> templeft 

因为您只是在本地定义该令牌,然后将其添加到组外。

   \expandafter\gappto\expandafter\matrixcontents\expandafter{\tempright \\}

添加扩展,\tempright然后\\\matrixcontents

 \expandafter\gappto\expandafter\matrixcontents{\expandafter 
    \consimg{\expandafter\templeft} \&}

前两个\expandafter应用扩展,{它是一个不可扩展的标记,因此它与

       \gappto\matrixcontents{\expandafter\consimg{\expandafter\templeft} \&}

所以增加\expandafter\consimg{\expandafter\templeft} \&\matrixcontents但 (a)\templeft那时还不会被定义并且 (b) 当使用这个时,第一个\expandafter再次适用于{所以什么也不做。

您想要\templeft按照案例进行扩展\tempright,因此:

        \expandafter\gappto\expandafter\matrixcontents\expandafter
                    {\expandafter\consimg\expandafter{\templeft} \&}

在此处输入图片描述

仅设置带有三个标签的三个图像似乎过于复杂,不清楚您为什么需要xstring或者tikz根本不需要,但也许您的真实文档使用了这些功能,而它只是一个小例子的产物。

\documentclass{article}

\usepackage{calc}
\usepackage{geometry}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{xstring}

% PAGE GEOMETRY
\geometry{a4paper,
          landscape,
          top=1cm,
          bottom=1cm,
          left=1cm,
          right=1cm,
          includehead,
          includefoot}
\usetikzlibrary{calc, matrix}
% END PAGE GEOMETRY

% META

% sizes
\newcommand{\unitsize}{1cm}

% #1 > (x,y)
% #2 > Object_Name (filename without .png)
% #3 Amount
% #4 > Comma Separated list: <stratum>:<amount>,<stratum>:<amount>, ...
% >{\SplitList{,}}
\NewDocumentCommand{\consnode}{m m m m}{
    \node (#2) at #1 {
        \let\matrixcontents\empty
        \foreach \c in {#4}{
            \StrBefore{\c}{:}[\templeft]
            \StrBehind{\c}{:}[\tempright]

            \expandafter\gappto\expandafter\matrixcontents\expandafter
                        {\expandafter\consimg\expandafter{\templeft} \&}
            \expandafter\gappto\expandafter\matrixcontents\expandafter{\tempright \\}
        }

        \begin{tikzpicture}
            \node[label={[label distance=-(0.35*\unitsize)]105:#3×}] at (0,0) {
                \includegraphics[width=\unitsize, height=\unitsize]{#2}};
            \matrix[row sep=-2mm, matrix of nodes, ampersand replacement=\&] (output) at (0,-1) {
                \matrixcontents
                %\includegraphics[width=\unitsize/2, height=\unitsize/2]{icons/example-image-b.png} \& 800 \\
                %\includegraphics[width=\unitsize/2, height=\unitsize/2]{icons/example-image-c.png} \& 1200 \\
                };
        \end{tikzpicture}};
}

\newcommand{\consimg}[1]{%
    \includegraphics[width=\unitsize/2, height=\unitsize/2]{#1}%
}

% END META

\begin{document}

\begin{tikzpicture}
    \consnode{(0,0)}{example-image-a}{1}{example-image-b:800,example-image-c:1200}
\end{tikzpicture}

\end{document}

相关内容