我是一名教师。当我出考试题时,我希望能够打印学生版的考试,然后打印考试答案。我的学生直接在考试卷上写答案,所以我留给他们写答案的空间通常足够大,可以容纳我想要的答案。问题是如何打印两个版本的考试。
请注意,我熟悉 EXAM 包(https://ctan.org/pkg/exam?lang=en),目前对使用它不感兴趣。查看其他答案,我认为我想要的是基于 smash 的东西(\smash 起什么作用?它的文档记录在哪里?)。
下面显示的是具有 \answerkey 的两个实现的 MWE。版本 A 是我尝试做我想做的事情——可选地包含答案,用红色表示,并将其粉碎,以便它不占用任何空间。不幸的是,对于下面的第一次使用,垂直间距在有答案和没有答案的情况下仍然会发生变化。对于下面的第二次使用,它完全中断,因为答案有多个段落。
最佳答案是单个 \answerkey 命令,它可以处理以下两种用途。目标是当使用 \answerstrue 或 \answersfalse 时文档的间距不会改变。
\documentclass[10pt]{article}
\usepackage{xcolor}
\usepackage{tikz}
\newif\ifanswers
\answerstrue
%\answersfalse
\newcommand{\answerkeyA}[1]{%
\ifanswers%
\textcolor{red}{\smash{\textbf{\parbox[t]{\linewidth}{#1}}}}%
\fi%
}
\newcommand{\answerkeyB}[1]{%
\ifanswers%
#1%
\fi%
}
\begin{document}
\begin{enumerate}
\item Answer the following question with words.
\answerkeyA{ I do not like them in a house. I do not like them with
a mouse. I do not like them here or there. I do not like them
anywhere. I do not like green eggs and ham. }
\vspace*{1in}
\item Draw a picture to illustrate the following problem.
\answerkeyB{
Answer:
\begin{tikzpicture}[scale=0.3,font=\sffamily]
\draw [step=1.0, thin, gray!50] (-3, -3) grid (3, 3);
\draw [arrows={latex-latex}] (-3,0) -- coordinate (x axis mid) (3,0);
\draw [arrows={latex-latex}] (0,-3) -- coordinate (y axis mid) (0,3);
\end{tikzpicture}
}
\vspace*{2in}
\item The next problem should be here.
\end{enumerate}
\end{document}
答案1
您可以执行\smash
后跟\vspace
,但\parbox
有用于控制其高度和宽度的参数。
我会这样做,给出逻辑转换\ifanswers
和为学生写答案的指定空间。
\newcommand\answer[2]{% #1 = size #2 = answer
\par \noindent
\parbox[t][#1][s]{\linewidth}{%
\ifanswers \color{red}#2\fi
\par\vfill
}\par
\setlength\prevdepth{0pt}\medskip
}
[s]
“拉伸”的参数和框\vfill
末尾的 结合起来就像一个[t]
参数,除了[t]
当文本无法放入分配的空间时没有警告。当答案文本太大时,此版本会发出框满警告,答案可以打印在下一个问题上。
答案上方有一点额外的空间,这可能正是所需要的。(这是由于答案的顶部边缘位于“基线”处造成的。)此外,答案\medskip
后面还有可选的额外空间以保持平衡。
再多做一些,\answer
就可以将宏收紧,以便在问题和答案之间提供规则的基线间距。
\newcommand\answer[2]{% #1 = size #2 = answer
\par \noindent
\parbox[t][#1][s]{\linewidth}{%
% the next line preserves the top baseline alignment
\vskip-\ht\strutbox \noindent\strut
\ifanswers \color{red}\ignorespaces#2\fi
\par\vfill
}\par
\setlength\prevdepth{0pt}%
}
在该版本中,段落在答案文本之前开始,并使用“支撑”加上否定将基线对齐到其所属的位置。允许\ignorespaces
将答案写成
\answer{3cm}{
this is the answer...
}
而不会引入虚假空间。
答案2
如果您希望间距不变,那么即使在学生版中您仍然需要对文本进行一些处理,以便 TeX 知道间距应该是多少。 \vphantom
将留下适当的垂直间距,但也会中断段落。此解决方案是无论如何都要写答案,但要用隐形墨水(又名白色)。唯一的问题是 tikzpicture 还设置了颜色,因此我还需要一个新的颜色命令:\answercolor
,它是您指定的颜色,或者是白色。(此外,\textcolor{white}{#1}
也不喜欢段落分隔,所以我改用{\color{white}#1}
。)(请注意,文本仍然存在,因此不适合以 pdf 形式提供 - 您可以复制并粘贴不可见的文本。但一旦打印出来,文本就不再存在了。
\documentclass[10pt]{article}
\usepackage{xcolor}
\usepackage{tikz}
\newif\ifanswers
%\answerstrue
\answersfalse
\newcommand{\answerkeyA}[1]{%
\ifanswers%
\textcolor{red}{\smash{\textbf{\parbox[t]{\linewidth}{#1}}}}%
\else%
\textcolor{white}{\smash{\textbf{\parbox[t]{\linewidth}{#1}}}}%
\fi%
}
\newcommand{\answerkeyB}[1]{%
\ifanswers%
#1%
\else%
{\color{white}#1}%
\fi%
}
\newcommand{\answercolor}[1]{%
\ifanswers%
#1%
\else%
white%
\fi%
}
\begin{document}
\begin{enumerate}
\item Answer the following question with words.
\answerkeyA{ I do not like them in a house. I do not like them with
a mouse. I do not like them here or there. I do not like them
anywhere. I do not like green eggs and ham. }
\vspace*{1in}
\item Draw a picture to illustrate the following problem.
\answerkeyB{
Answer:
\begin{tikzpicture}[scale=0.3,font=\sffamily]
\draw [step=1.0, thin, \answercolor{gray!50}] (-3, -3) grid (3, 3);
\draw [arrows={latex-latex}] (-3,0) -- coordinate (x axis mid) (3,0);
\draw [arrows={latex-latex}] (0,-3) -- coordinate (y axis mid) (0,3);
\end{tikzpicture}
}
\vspace*{2in}
\item The next problem should be here.
\end{enumerate}
\end{document}
答案3
我想这可能就是你想要的。此解决方案提供了answer
环境,你只需要将答案放入其中。你可以通过激活在教师/学生版本之间切换\answerfalse
。
教师版:
学生版:
关于此解决方案的更多详细信息:
- 我正在使用
xparse
来捕获环境主体answer
。请注意,这需要较新版本的xparse
。如果您无法访问它,请考虑改用environ
包。 - 将内容放入可拆分文件
tcolorbox
中以测量高度。将内容放入输入流后,tcolorbox
将负责将内容拆分到多个页面。 - 假设您不会改变
\baselinestretch
——如果行距发生变化,则可能需要修改计算。 - 当
\answerfalse
激活时,我将tcolorbox
用高度等于原始内容的新行来填充。 - 因为环境的主体被捕获为参数,所以您将无法在里面使用逐字环境
answer
(例如align
,,,等等)align*
listing
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath, amssymb}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{tikz}
\usepackage{blindtext}
\usepackage[breakable, skins]{tcolorbox}
\ExplSyntaxOn
\bool_new:N \g_show_answer_bool
\coffin_new:N \g_answer_coffin
\dim_new:N \g_answer_height_dim
\dim_new:N \g_answer_parbox_height_dim
% unit height of each \parbox for tcolorbox's
% page breaking algorithm to work with
\dim_gset:Nn \g_answer_parbox_height_dim {\baselineskip}
\newcommand{\answertrue}{\bool_gset_true:N \g_show_answer_bool}
\newcommand{\answerfalse}{\bool_gset_false:N \g_show_answer_bool}
% shows answer by default
\answertrue
\cs_set:Npn \my_tcbox:nn #1#2 {
\begin{tcolorbox}[breakable, enhanced, left=0pt, right=0pt, top=0pt, bottom=0pt, boxsep=0pt, boxrule=0pt, colback=white, colframe=white, width=\linewidth, #2]
#1
\end{tcolorbox}
}
\cs_generate_variant:Nn \my_tcbox:nn {Vn}
\cs_set:Npn \my_height_box:n #1 {
\exp_not:n{\parbox{\linewidth}{\rule{0pt}{#1}}}
}
% +b (body capture) requires `xparse` package to be no older than 2019-03-05 release
% or one can use environ package to achieve similar effects
\DeclareDocumentEnvironment{answer}{+b}{
\bool_if:NTF \g_show_answer_bool {
% shows answer
\my_tcbox:nn {#1} {}
} {
% otherwise, use content that has identical height instead
% put content in a minipage to measure height
\hcoffin_gset:Nn \g_answer_coffin {
\my_tcbox:nn {#1} {}
}
% get height of content
\dim_gset:Nn \g_answer_height_dim {
\coffin_dp:N \g_answer_coffin +
\coffin_ht:N \g_answer_coffin +
\baselineskip
}
% check if height of content is longer than current page
\fp_compare:nNnT {\g_answer_height_dim} > {\pagegoal - \pagetotal} {
% if so, increase \g_answer_height_dim
\dim_gadd:Nn \g_answer_height_dim {\baselineskip}
}
% compute how many units we need
\fp_set:Nn \l_tmpa_fp {floor(\g_answer_height_dim / \g_answer_parbox_height_dim)}
% create token list to fill vspace
\tl_set:Nn \l_tmpa_tl {}
\fp_step_inline:nnnn {1} {1} {\l_tmpa_fp} {
\tl_put_right:Nn \l_tmpa_tl {\par\phantom{}}
}
% compute space less than \g_answer_parbox_height_dim
\fp_set:Nn \l_tmpb_fp {\g_answer_height_dim - \l_tmpa_fp * \g_answer_parbox_height_dim}
% fill remaining space
\tl_put_right:Nx \l_tmpa_tl {\exp_not:N\vspace*{\fp_eval:n {\l_tmpb_fp} pt}}
%\tl_show:N \l_tmpa_tl
\my_tcbox:Vn \l_tmpa_tl {}
}
}{}
\ExplSyntaxOff
% toggle version w/ or w/out answer
%\answerfalse
\begin{document}
\begin{enumerate}
\item Answer the following question with words.
\begin{answer}
I do not like them in a house. I do not like them with a mouse.
I do not like them here or there. I do not like them anywhere.
I do not like green eggs and ham.
\end{answer}
\item Draw a picture to illustrate the following problem.
\begin{answer}
\begin{tikzpicture}[scale=0.3,font=\sffamily]
\draw [step=1.0, thin, gray!50] (-3, -3) grid (3, 3);
\draw [arrows={latex-latex}] (-3,0) -- coordinate (x axis mid) (3,0);
\draw [arrows={latex-latex}] (0,-3) -- coordinate (y axis mid) (0,3);
\end{tikzpicture}
\end{answer}
\item Write a long and useless article.
\begin{answer}
\Blindtext[4]
\end{answer}
\end{enumerate}
Space to top page top: \the\pagetotal
\end{document}