TikZ 解决方案集未编译

TikZ 解决方案集未编译

我以前曾使用 TikZ 做过练习和解决方案表,所以我不确定为什么会失败。

这只是一组极其简单的 2+2=?练习及其解决方案。

我希望它能将问题隔离开来我之前的帖子

\Solution我在“打破这一点”的定义中写了什么?

\documentclass{article}

\usepackage{tikz}

\newcommand{\GenerateExerciseAndSolution}
 {\newcommand{\Exercise}
  {\begin{tikzpicture}
   \node at (0,0) {$2+2=?$};
   \end{tikzpicture}

   }
  \newcommand{\Solution}
   {\begin{tikzpicture}
    \node at (0,0) {$2+2=4$};
    \end{tikzpicture}

   }
  }

\setlength{\parindent}{0cm}

\begin{document}

\section*{Exercises}

\newcommand{\SolutionSet}{}

\foreach \x in {1,...,5}
 {\GenerateExerciseAndSolution (\x) \Exercise \par
  \xdef\SolutionSet{\SolutionSet (\x) \Solution \par} % This compiles if I delete "\Solution" from this line.
  }

\section*{Solutions}

\SolutionSet

\end{document}

答案1

错误的原因在于\xdef尝试完全扩展给定的内容,但 LaTeX 中并非所有内容都是可扩展的。特别是,像tikzpicture环境这样的“复杂”对象不太可能扩展。您似乎假设\xdef只会将“当前值”插入其中\Solution\SolutionSet但实际上 LaTeX 尝试添加大量代码,\SolutionSet而这根本行不通。

正如您在评论中所说,“‘不要使用 xdef’ 不是一个解决方案”,但我认为没有简单的方法可以解决您正在做的事情,因为底层方法存在缺陷(抱歉!)。使用蒂克兹排版问题及其解决方案的列表当然是新颖的,但这并没有发挥 的优势tikz,因为 主要用于绘制图形。enumerate环境之类的东西可能更适合显示练习。

我怀疑您之所以使用是\tikz因为您想利用它\foreach,但对于您想做的事情,存在一大堆扩展障碍需要您解决,而我认为您不想去那里。

相反,我建议你看看\docsvlist查看电子工具箱包。这可用于处理逗号分隔变量的“列表”。您似乎正在处理的练习集类型很容易写成逗号分隔列表:

 1+1 = 2,
 1+2 = 3,
 1+3 = 4,
 2+2 = 4

这也适用于更复杂的练习,但您应该避免使用逗号并且只使用一个等号 - 或更改语法!

给定其中一个“练习”,我们需要将练习和解决方案分开。现代 LaTeX 的方法是使用\SplitArgument 使用解析包,但我们只使用普通的 TeX hack 来代替:

\def\printExercise#1=#2!!!{\item $#1=\space?$}

因此,\printExercise 1+1 = 2!!!将设置为#1等于1+1并将结果添加到输入流中。该命令将命令应用于给定的列表的每个元素,因此我们只需要让给出练习到。我们还需要一个相应的宏。希望这足以解释为什么以下代码#22\item $1+1=\space?$\docsvlist\do\do\printExercise\printSolution

\documentclass{article}

\usepackage{etoolbox}
\usepackage{enumitem}

\def\printExercise#1=#2!!!{\item $#1=\space?$}
\def\printSolution#1=#2!!!{\item $#1=#2$}

\newcommand\PrintExercises[1]{%
  \section*{Exercises}
  \renewcommand*\do[1]{\printExercise##1!!!}
  \begin{enumerate}[label=(\arabic*)]
    \docsvlist{#1}
  \end{enumerate}

  \section*{Solutions}
  \renewcommand*\do[1]{\printSolution##1!!!}
  \begin{enumerate}[label=(\arabic*)]
    \docsvlist{#1}
  \end{enumerate}
}

\begin{document}

\PrintExercises{% comma separated list of exercise: solution pairs
     1+1 = 2,
     1+2 = 3,
     1+3 = 4,
     2+2 = 4
}

\end{document}

产生类似于您正在寻找的输出(我认为):

在此处输入图片描述

事实上,由于\printSolution正在打印“完整的练习解决方案方程”,并且不对#1或进行任何操作#2,我们可以用 替换\renewcommand*\do[1]{\printSolution##1!!!}上面的内容\renewcommand*\do[1]{\item $##1$}。我们只需要一个\printSolution宏来对解决方案进行“更复杂”的处理——例如,如果我们只想打印解决方案而不是完整的方程。

这里的主要技巧是将数据(即练习和解决方案)与我们需要显示它的周围 LaTeX 代码分开。我认为将数据的相关部分(在本例中为练习及其解决方案)尽可能地放在一起始终是一个好主意。

相关内容