为什么反转列表在 LaTeX2e 中有效,但在 LaTeX3 中无效?

为什么反转列表在 LaTeX2e 中有效,但在 LaTeX3 中无效?

这是我的延伸上一个问题

这是我的项目代码的 LaTeX2e 版本。

\documentclass{article}
\usepackage{tikz}
\usepackage{xargs}
\usepackage{xstring} % needed for \StrCount
\usepackage{ifthen}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{arev}
\usepackage[T1]{fontenc}

\newcommandx{\tensormachinetwoe}[2][1]{%
  % For aesthetic reasons, we need to reverse the order of #1. 
  \let\revslots\empty
  \foreach \x in {#1}{%
    \ifx\revslots\empty
      \xdef\revslots{\x}
    \else
      \xdef\revslots{\x,\revslots}
    \fi
  }%
  \begin{tikzpicture}[baseline]
    \pgfmathsetmacro{\cubex}{4}
    \pgfmathsetmacro{\cubey}{1}
    \pgfmathsetmacro{\cubez}{3}
    \pgfmathsetmacro{\slotwidth}{1}

    % front
    \draw[fill=white,thick] (0.5*\cubex,0.5*\cubey,0.5*\cubez) -- 
      ++(-\cubex,0,0) -- ++(0,-\cubey,0) -- ++(\cubex,0,0) -- cycle
      % label the machine
      node at (0.30*\cubex,0,0.5*\cubez) {\(\boldsymbol{\mathbf{#2}}\)};
    % side
    \draw[fill=white,thick] (0.5*\cubex,0.5\cubey,-0.5*\cubez) --    
      ++(0,0,\cubez) -- ++(0,-\cubey,0) -- ++(0,0,-\cubez) -- cycle;
    % top
    \draw[fill=white,thick] (0.5*\cubex,0.5*\cubey,-0.5*\cubez) --
      ++(-\cubex,0,0) -- ++(0,0,\cubez) -- ++(\cubex,0,0) -- cycle;
    % output slot
    \draw[fill=black, ultra thick] (-0.5*\slotwidth,0,0.5*\cubez) -- 
      ++(0,0.03,0) -- ++(\slotwidth,0,0) -- ++(0,-0.03,0) -- cycle;
    %\fill (0,0,0) circle (2pt); % origin
    
    \ifthenelse{\equal{#1}{}}%
      {% We have a scalar. Fill the output slot and we're done.
        \draw[fill=white, thin,-] (-0.5*\slotwidth+0.1,0,0.5*\cubez) 
          -- ++(-0.25,-\slotwidth,0) -- ++(\slotwidth-0.2,0,0) 
          -- ++(0.25,\slotwidth,0) 
          node at (-0.125*\slotwidth,-0.5*\cubey,0.5*\cubez) {\(\mathbb{R}\)};
      }%
      {% We have slots, which may be filled or unfilled.
        % Set some values.
        \StrCount{#1,}{,}[\numslots]
        \StrCount{#1}{+}[\numfilledslots]
        \pgfmathsetmacro{\startvslotx}{-0.25*\cubex-0.5*\slotwidth}
        \pgfmathsetmacro{\startoslotx}{+0.25*\cubex-0.5*\slotwidth}
        \pgfmathsetmacro{\sloty}{0.5*\cubey}
        \pgfmathsetmacro{\totalnumslots}{\numslots}
        \pgfmathsetmacro{\slotspace}{\cubez / (\totalnumslots + 1)}
        \pgfmathsetmacro{\islotspaceindex}{1}
        % Loop through the reversed list of slots.
        \foreach \currentslot in \revslots {%
          \IfBeginWith{\currentslot}{v}%
            {% Draw a vector slot.
              \draw[fill=black, ultra thick]
                (\startvslotx,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                -- ++(0,0,0.04) -- ++(\slotwidth,0,0) -- ++(0,0,-0.04) -- cycle;
              % Test to see if we need to fill the slot.
              \IfEndWith{\currentslot}{+}%
                {% Fill the slot.
                  \draw[fill=white,thin]
                   (\startvslotx+0.1,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                   -- ++(0,\slotwidth,0) -- ++(\slotwidth-0.2,0,0) -- ++(0,-\slotwidth,0);
                }%
                {% Leave it empty.
                }%
            }%
            {% Draw a 1-form slot.
              \draw[fill=black, ultra thick]
                (\startoslotx,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                -- ++(0,0,0.04) -- ++(\slotwidth,0,0)-- ++(0,0,-0.04) -- cycle; 
              % Test to see if we need to fill the slot.
              \IfEndWith{\currentslot}{+}%
                {% Fill the slot.
                  \draw[fill=lightgray,thin]
                    (\startoslotx+0.1,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                    -- ++(0,\slotwidth,0) -- ++(\slotwidth-0.2,0,0) -- ++(0,-\slotwidth,0);
                }%
                {% Leave it empty.
                }%
            }%
          \pgfmathparse{\islotspaceindex+1}
          \xdef\islotspaceindex{\pgfmathresult}
        }%
        % Test to see if we need to fill the output slot.
        \ifthenelse{\equal{\numslots}{\numfilledslots}}%
        {% Fill the output slot.
          \draw[fill=white, thin,-] (-0.5*\slotwidth+0.1,0,0.5*\cubez) 
             -- ++(-0.25,-\slotwidth,0) -- ++(\slotwidth-0.2,0,0) 
             -- ++(0.25,\slotwidth,0) 
             node at (-0.125*\slotwidth,-0.5*\cubey,0.5*\cubez) {\(\mathbb{R}\)};
        }%
        {% Leave it empty.
        }%
      }%
  \end{tikzpicture}
}%

\begin{document}
\[
\tensormachinetwoe[v,o]{T}
\]
\[
\tensormachinetwoe[o+,v+]{T}
\]
\[
\tensormachinetwoe[o+,o+,v+]{T}
\]
\[
\tensormachinetwoe{}
\]
\end{document}

以下是同一项目的 LaTeX3 版本:

\documentclass{article}
\usepackage{tikz}
\usepackage{expl3} % seems to be optional
\usepackage{xparse}
\usepackage{xstring} % needed for \StrCount
\usepackage{ifthen}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{arev}
\usepackage[T1]{fontenc}

\ExplSyntaxOn
\NewDocumentCommand{\tensormachinetwoe}{ m O{} O{} }{%
  % For aesthetic reasons, we need to reverse the order of #1. 
  \clist_clear_new:N \revslots
  \clist_set:Nn \revslots {\clist_reverse:n #1}
  \begin{tikzpicture}[baseline]
    \pgfmathsetmacro{\cubex}{4}
    \pgfmathsetmacro{\cubey}{1}
    \pgfmathsetmacro{\cubez}{3}
    \pgfmathsetmacro{\slotwidth}{1}

    % front
    \draw[fill=white,thick] (0.5*\cubex,0.5*\cubey,0.5*\cubez) -- 
      ++(-\cubex,0,0) -- ++(0,-\cubey,0) -- ++(\cubex,0,0) -- cycle
      % label the machine
      node at (-0.30*\cubex,0,0.5*\cubez) {\(\boldsymbol{\mathbf{#2}}\)}
      node at (0.30*\cubex,0,0.5*\cubez) {\(\boldsymbol{\mathbf{#3}}\)};
    % side
    \draw[fill=white,thick] (0.5*\cubex,0.5\cubey,-0.5*\cubez) --    
      ++(0,0,\cubez) -- ++(0,-\cubey,0) -- ++(0,0,-\cubez) -- cycle;
    % top
    \draw[fill=white,thick] (0.5*\cubex,0.5*\cubey,-0.5*\cubez) --
      ++(-\cubex,0,0) -- ++(0,0,\cubez) -- ++(\cubex,0,0) -- cycle;
    % output slot
    \draw[fill=black, ultra~thick] (-0.5*\slotwidth,0,0.5*\cubez) -- 
      ++(0,0.03,0) -- ++(\slotwidth,0,0) -- ++(0,-0.03,0) -- cycle;
    %\fill (0,0,0) circle (2pt); % origin
    
    \ifthenelse{\equal{#1}{}}%
      {% We have a scalar. Fill the output slot and we're done.
        \draw[fill=white, thin,-] (-0.5*\slotwidth+0.1,0,0.5*\cubez) 
          -- ++(-0.25,-\slotwidth,0) -- ++(\slotwidth-0.2,0,0) 
          -- ++(0.25,\slotwidth,0) 
          node at (-0.125*\slotwidth,-0.5*\cubey,0.5*\cubez) {\(\mathbb{R}\)};
      }%
      {% We have slots, which may be filled or unfilled.
        % Set some values.
        \StrCount{#1,}{,}[\numslots]
        \StrCount{#1}{+}[\numfilledslots]
        \pgfmathsetmacro{\startvslotx}{-0.25*\cubex-0.5*\slotwidth}
        \pgfmathsetmacro{\startoslotx}{+0.25*\cubex-0.5*\slotwidth}
        \pgfmathsetmacro{\sloty}{0.5*\cubey}
        \pgfmathsetmacro{\totalnumslots}{\numslots}
        \pgfmathsetmacro{\slotspace}{\cubez / (\totalnumslots + 1)}
        \pgfmathsetmacro{\islotspaceindex}{1}
        % Loop through the reversed list of slots.
        \foreach \currentslot in \revslots {%
          %\node at (4,0,0) {\currentslot}; % debug
          \IfBeginWith{\currentslot}{v}%
            {% Draw a vector slot.
              \draw[fill=black, ultra~thick]
                (\startvslotx,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                -- ++(0,0,0.04) -- ++(\slotwidth,0,0) -- ++(0,0,-0.04) -- cycle;
              % Test to see if we need to fill the slot.
              \IfEndWith{\currentslot}{+}%
                {% Fill the slot.
                  \draw[fill=white,thin]
                   (\startvslotx+0.1,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                   -- ++(0,\slotwidth,0) -- ++(\slotwidth-0.2,0,0) -- ++(0,-\slotwidth,0);
                }%
                {% Leave it empty.
                }%
            }%
            {% Draw a 1-form slot.
              \draw[fill=black, ultra~thick]
                (\startoslotx,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                -- ++(0,0,0.04) -- ++(\slotwidth,0,0)-- ++(0,0,-0.04) -- cycle; 
              % Test to see if we need to fill the slot.
              \IfEndWith{\currentslot}{+}%
                {% Fill the slot.
                  \draw[fill=lightgray,thin]
                    (\startoslotx+0.1,\sloty,-0.5*\cubez+\islotspaceindex*\slotspace) 
                    -- ++(0,\slotwidth,0) -- ++(\slotwidth-0.2,0,0) -- ++(0,-\slotwidth,0);
                }%
                {% Leave it empty.
                }%
            }%
          \pgfmathparse{\islotspaceindex+1}
          \xdef\islotspaceindex{\pgfmathresult}
        }%
        % Test to see if we need to fill the output slot.
        \ifthenelse{\equal{\numslots}{\numfilledslots}}%
        {% Fill the output slot.
          \draw[fill=white, thin,-] (-0.5*\slotwidth+0.1,0,0.5*\cubez) 
             -- ++(-0.25,-\slotwidth,0) -- ++(\slotwidth-0.2,0,0) 
             -- ++(0.25,\slotwidth,0) 
             node at (-0.125*\slotwidth,-0.5*\cubey,0.5*\cubez) {\(\mathbb{R}\)};
        }%
        {% Leave it empty.
        }%
      }%
  \end{tikzpicture}
}%
\ExplSyntaxOff

\begin{document}
\[
\tensormachinetwoe{v,o}[T]
\]
\[
\tensormachinetwoe{o+,v+}[T]
\]
\[
\tensormachinetwoe{o+,o+,v+}[T]
\]
\[
\tensormachinetwoe{}
\]
\end{document}

结果必须完全相同,而且几乎完全相同。在 LaTeX3 版本中,机器顶部的插槽以与实际绘制顺序相反的顺序绘制,尽管在一开始就已将其反转\tensormachinetwoe就像在 LaTeX2e 版本中一样。如果在 LaTeX3 版本中,我将线更改\clist_set:Nn \revslots {\clist_reverse:n #1}\clist_set:Nn \revslots {\clist_reverse:n {#1}}第一个插槽绘制在正确的位置,但后续插槽不会绘制。没有错误消息。我是否遗漏了 LaTeX3 版本中显而易见的东西?

答案1

使用 Ti下面的 Z 代码\ExplSyntaxOn是不可能的,因为空格会被忽略。

你只需要定义一个“反转”命令:

\ExplSyntaxOn
\NewDocumentCommand{\reverselist}{mm}
 {
  \clist_clear_new:N #1
  \clist_set:Nx #1 { \clist_reverse:n { #2 } }
 }
\ExplSyntaxOff

并在外部启动你的代码\ExplSyntaxOn

全部ultra~thick改为ultra thick

\NewDocumentCommand{\tensormachinetwoe}{ m O{} O{} }{%
  % For aesthetic reasons, we need to reverse the order of #1. 
  \reverselist{\revslots}{#1}
  \begin{tikzpicture}[baseline]
  [...]

相关内容