问题发生重大变化后

问题发生重大变化后

原始问题如下(这是对我遇到的问题的一个糟糕的简化,而且在编辑之前,它还包含重大语法错误)。引发这个问题的问题是为什么\test\ttest工作,但\tttest给出!软件包 pgfbasematrix 错误:单个“&”符号与错误的 catcode 一起使用。

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{matrix}
 \def\test #1.{#1}
 \def\ttest #1.{\node{#1}}
 \def\tttest #1, #2.{\node{#1}; & \node{#2};}
\begin{document}
\begin{tikzpicture}
\matrix [draw,row sep=1cm,nodes=draw]
{\node  {10}; & \node {5};  \\
\node  {5}; & \node  {\test 10.}; \\};
\end{tikzpicture}
\newpage
\begin{tikzpicture}
\matrix [draw,row sep=1cm,nodes=draw]
{\node  {10}; & \ttest 5. ;  \\
\node  {5}; & \node  {\test 10.}; \\};
\end{tikzpicture}
\newpage
\begin{tikzpicture}
\matrix [draw,row sep=1cm,nodes=draw]
{\tttest 10, 5. \\
\node  {5}; & \node  {\test 10.}; \\};
\end{tikzpicture}
\end{document}

原始问题:

假设 Bob(我们虚构的人物)整天都要使用 AMS-TeX 输入很长的方程组。可怜的 Bob 非常疲惫,但有一天他突然顿悟:TeX 之书!Bob 读了第 7 章和第 20 章,认为他解决了问题。

无需输入:

 \begin{align*}
 & 2x + & 10y =& 20 \\
 & x  - & y   =& 10 \\
 \end{align*}

Bob 创建了一个宏并认为问题已经解决:

\def\bobmacro #1, #2, #3{ & #1 & #2 & #3 \\}
\begin{align*}
 \bobmacro{ 2x+, 10y=, 20}
 \bobmacro{ x-, y, 10}
 \end{align*}

但可惜的是!宏无法编译,Bob 怀疑问题出在 cat 代码上&,也可能是//。他知道他可以通过使用 来消除它们\string,并且这样做代码可以编译,但结果仍然不是所期望的。

Bob 去 TeX.SE 看了关于\csname和 的问题\scantokens。最后一个问题看起来很有希望,但他在 Google 上找不到一个简单的例子。

Bob 似乎比刚开始时更加困惑。他想知道:是否有一种 TeX/LaTeX 或 e-TeX 方式来实现他的宏背后的想法?

答案1

塞尔吉奥,对不起,鲍勃使用了错误的工具,因为提供的对齐align肯定不是线性系统所需要的。

类别代码与此问题无关,也\scantokens无济于事;\string&完全是错误的。问题是,除非以不太简单的方式定义宏,否则您无法拥有跨越对齐中的两个单元格的宏。

但是 Sergio,抱歉,Bob,有一个更好的方法,通过systeme包提供。文档是法语的,但有很多例子。

\documentclass{article}
\usepackage{systeme}

\begin{document}
\[
\systeme{
 2x + 10y = 20,
  x -   y = 10
}
\]
\end{document}

在此处输入图片描述

如果你不想要括号,请添加

\sysdelim..

在您的文档前言中或者\systeme在您不想使用括号的命令之前。


问题发生重大变化后

这是 TikZ 和库的一个已知限制matrix。& 符号非常特殊,不应该出现在环境中调用的参数或宏中tikzpicture。解决方法是使用ampersand replacement; 我一直都在使用它,尽管在前两个例子中它不是必需的。

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{matrix}
 \def\test #1.{#1}
 \def\ttest #1.{\node{#1}}
 \def\tttest #1, #2.{\node{#1}; \& \node{#2};}

\begin{document}

\begin{tikzpicture}
\matrix [draw,row sep=1cm,nodes=draw,ampersand replacement=\&]
{\node  {10}; \& \node {5};  \\
\node  {5}; \& \node  {\test 10.}; \\};
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\matrix [draw,row sep=1cm,nodes=draw,ampersand replacement=\&]
{\node  {10}; \& \ttest 5. ;  \\
\node  {5}; \& \node  {\test 10.}; \\};
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\matrix [draw,row sep=1cm,nodes=draw,ampersand replacement=\&]
{\tttest 10, 5. \\
\node  {5}; \& \node  {\test 10.}; \\};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

除了所有关于该方法是否合适的评论之外,上面的方法根本不起作用,因为它\bobmacro被定义为一个带有 2 个分隔参数(用逗号分隔)的宏,后跟一个普通参数,但它随后被调用为一个带有单个参数的宏,因此需要这样调用它

\begin{align*}
 \bobmacro 2x+, 10y=, {20}
 \bobmacro  x-, y, {10}
\end{align*}

在这种情况下,它会产生与原始完全相同的输出,align*尽管输入语法非常奇怪。

我建议 Bob(我们的虚构人物)应该重读第 20 章(关于如何确定参数的部分),以了解他定义了什么以及如何改进语法。@fjbu 给出的答案显示了如何实现他的输入语法。

答案3

定义这样的宏没有任何实际意义:

\documentclass{article}
\usepackage{amsmath}
\makeatletter
\def\bobmacro#1{\expandafter\bobmacro@i#1\@nil}
\def\bobmacro@i#1,#2,#3\@nil{ & #1 & #2 & #3 \\}
\makeatother

\begin{document}
\begin{align}
 \bobmacro{ 2x+, 10y=, 20}
 \bobmacro{ x-, y, 10}
\end{align}

\begin{align}
 2x+ 10y &= 20\\
  x-   y &= 10
\end{align}

\end{document}

您需要为最后一行使用不同的宏,align不要像\\末尾那样:

在此处输入图片描述

答案4

这是解决此问题的 LaTeX 方法。我同时使用pgfformathtools。使用这些包并不是完全必要的,但创建循环来迭代行并控制内部扩展会多一些工作\xdef

\documentclass{article}

\usepackage{amsmath,amssymb}
\usepackage{etoolbox}
\usepackage{pgffor}

\makeatletter

\let\bob@align\relax
\let\bob@row\relax

\def\bob@build@row#1{%%
  \let\bob@row\relax
  \foreach \myi in {#1}
  {%%
    \ifx\bob@row\relax
      \xdef\bob@row{\myi}%%
    \else 
      \xdef\bob@row{\bob@row & \myi}%%
    \fi
  }%% 
  \xdef\bob@row{\bob@row \noexpand\\}%%
}

\def\bobmacro#1{%%
  \let\bob@align\relax
  \foreach \myn in {#1}
  {%%
    \ifx\bob@align\relax
      \expandafter\bob@build@row\expandafter{\myn}%%
      \xdef\bob@align{\expandonce\bob@row}%%
    \else
      \expandafter\bob@build@row\expandafter{\myn}%%
      \xdef\bob@align{\expandonce\bob@align \expandonce\bob@row}%%
    \fi
  }
  \begin{align*}
    \bob@align
  \end{align*}
  }

\makeatother

\begin{document}

\bobmacro{%%
  {2x+, 10y=, 20},
  {x-,y=,10}%%
  }

compare with:

\begin{align*}
  2x + & 10y = & 20 \\
  x  - &   y=  & 10 
\end{align*}

\end{document}

在此处输入图片描述

这个想法是使用两个宏:

  • 一个用于构建单独的行
  • 另一个用于构建完成的align*环境。

你确实需要小心错误的空白裁剪和破坏事物:

 \bobmacro{%%
  {2x+, 10y=, 20},
  {x-,y=,10}
  }

看上去相当无害,但\pgffor看到末尾的空格{x-,y=,10},然后不会去掉括号。

相关内容