隐藏内容以便稍后显示

隐藏内容以便稍后显示

我的问题出现在此egreg 的回答

我有一个练习答案列表,但我不想立即显示答案,而是等到我用命令拉取并获取到那里的所有答案。

举例来说:

\hidesolutions
\begin{exercise} this is an exercise.1 \end{exercise}
\begin{solution}  this is a solution for the above exercise.1  \end{solution}

\begin{exercise} this is an exercise.2 \end{exercise}
\begin{solution}  this is a solution for the above exercise.2  \end{solution}
\stophidesolutions

\begin{exercise} this is an exercise.3 \end{exercise}
\begin{solution}  this is a solution for the above exercise.3  \end{solution}

\hidesolutions
\begin{exercise} this is an exercise.4 \end{exercise}
\begin{solution}  this is a solution for the above exercise.4  \end{solution}

\begin{exercise} this is an exercise.5 \end{exercise}
\begin{solution}  this is a solution for the above exercise.5  \end{solution}
\stophidesolutions

\section{solutions}
\showsolutions 
\showsolutions

结果应该是:

  1. 显示练习 1 和 2
  2. 显示练习 3 和他的答案
  3. 显示练习 4 和 5
  4. 显示新部分solutions
  5. 显示答案 1 和 2
  6. 显示答案 4 和 5

答案1

有以下可能性:

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\usepackage{environ}

\theoremstyle{definition} % body text is upright
\newtheorem{exercise}{Exercise}

\ExplSyntaxOn
\newtheorem*{innersolution}{Solution ~ of ~ \dvvv_exercise_ref:}

\NewEnviron{solution}
 {
  \seq_gput_right:Nx \g_dvvv_solution_group_seq { {\theexercise}{\exp_not:V \BODY} }
 }
\NewDocumentEnvironment{solution*}{}
 {
  \cs_set:Npx \dvvv_exercise_ref: { \theexercise }
  \innersolution
 }
 {
  \endinnersolution
 }
\NewDocumentCommand{\printsolutions}{}
 {
  \seq_map_inline:Nn \g_dvvv_solution_group_seq
   {
    \dvvv_print_solutions:nn ##1
   }
  \seq_gclear:N \g_dvvv_solution_group_seq
 }

\seq_new:N \g_dvvv_solution_group_seq
\cs_new_protected:Npn \dvvv_print_solutions:nn #1 #2
 {
  \cs_set:Npn \dvvv_exercise_ref: { #1 }
  \begin{innersolution} #2 \end{innersolution}
 }
\ExplSyntaxOff

\begin{document}

\chapter{Title}

\section{Exercises}

\begin{exercise}
This is an exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is an exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is an exercise.
\end{exercise}

Some optional text in between.

\begin{solution*}
This is a solution.
\end{solution*}

The solution has been printed immediately, because
\texttt{solution*} has been used.

\begin{exercise}
This is another exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is yet another exercise.
\end{exercise}
\begin{solution}
Too much.
\end{solution}

\section{Solutions}
\printsolutions

\end{document}

解决方案存储在 FIFO 列表中;使用solution*可当场打印解决方案。

在此处输入图片描述

以下是相同的,但支持超链接:

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\usepackage{environ}
\usepackage[colorlinks]{hyperref}

\theoremstyle{definition} % body text is upright
\newtheorem{innerexercise}{Exercise}

\ExplSyntaxOn
\NewDocumentEnvironment{exercise}{}
 {
  \innerexercise\label{dvvv_ \theinnerexercise _label}
 }
 {
  \endinnerexercise
 }
\newtheorem*{innersolution}{\dvvv_exercise_ref:}

\NewEnviron{solution}
 {
  \seq_gput_right:Nx \g_dvvv_solution_group_seq
   {
    {\theinnerexercise}{\exp_not:V \BODY}
   }
 }
\NewDocumentEnvironment{solution*}{}
 {
  \cs_set:Npx \dvvv_exercise_ref:
   {
    \exp_not:N \hyperref
     [
      dvvv_ \theinnerexercise _label
     ]
     {
      Solution~of~\exp_not:N\ref*{dvvv_ \theinnerexercise _label}
     }
   }
  \innersolution
 }
 {
  \endinnersolution
 }
\NewDocumentCommand{\printsolutions}{}
 {
  \seq_map_inline:Nn \g_dvvv_solution_group_seq
   {
    \dvvv_print_solutions:nn ##1
   }
  \seq_gclear:N \g_dvvv_solution_group_seq
 }

\seq_new:N \g_dvvv_solution_group_seq
\cs_new_protected:Npn \dvvv_print_solutions:nn #1 #2
 {
  \cs_set:Npn \dvvv_exercise_ref:
   {
    \hyperref[dvvv_#1_label]{Solution~of~\ref*{dvvv_#1_label}}
   }
  \begin{innersolution} #2 \end{innersolution}
 }
\ExplSyntaxOff

\begin{document}

\chapter{Title}

\section{Exercises}

\begin{exercise}
This is an exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is an exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is an exercise.
\end{exercise}

Some optional text in between.

\begin{solution*}
This is a solution.
\end{solution*}

The solution has been printed immediately, because
\texttt{solution*} has been used.

\begin{exercise}
This is another exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is yet another exercise.
\end{exercise}
\begin{solution}
Too much.
\end{solution}

\section{Solutions}
\printsolutions

\end{document}

在此处输入图片描述

让我们一步一步地看一下第一个解决方案。第二个解决方案只是为每个exercise环境自动添加一个标签设置,用于超链接,所以它不会复杂太多。

步骤1

定义一个exercise环境;这是标准的

第2步

将环境定义innersolution为无编号定理;标签文本取决于\dvvv_exercise_ref:打印时设置的值

步骤3

定义一个solution环境,借助\NewEnviron,使 LaTeX 将环境的内容存储在宏 中\BODY。宏的值与当前练习编号一起存储在一个序列中。

步骤4

环境solution*只是将的值设置\dvvv_exercise_ref:为当前练习编号并调用innersolution

步骤5

定义\printsolutions命令,该命令只是映射序列,即传递给\dvvv_print_solutions:nn其每个项目。最后它清除序列。

第 6 步

\dvvv_print_solutions:nn函数利用了解决方案以 格式存储的事实{<number>}{<contents>},因此它使用第一个参数来设置 的值\dvvv_exercise_ref:,并将第二个参数提供给innersolution环境。

反向链接(从练习到解决方案)

诀窍是在解决方案中添加另一个标签,并在练习中添加超链接。

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\usepackage{environ}
\usepackage[colorlinks]{hyperref}

\newtheoremstyle{exercise}% name
  {\topsep}%     Space above
  {\topsep}%     Space below
  {\normalfont}% Body font
  {}%            Indent amount (empty = no indent, \parindent = para indent)
  {\bfseries}%   Thm head font
  {.}%           Punctuation after thm head
  { }%           Space after thm head
  {\hyperref[dvvv_#2_reverse_label]{\thmname{#1}\thmnumber{ #2}}\thmnote{ (#3)}}% Thm head spec

\theoremstyle{exercise} % body text is upright
\newtheorem{innerexercise}{Exercise}
\theoremstyle{definition}

\ExplSyntaxOn
\NewDocumentEnvironment{exercise}{}
 {
  \innerexercise\label{dvvv_ \theinnerexercise _label}
 }
 {
  \endinnerexercise
 }
\newtheorem*{innersolution}{\dvvv_exercise_ref:}

\NewEnviron{solution}
 {
  \seq_gput_right:Nx \g_dvvv_solution_group_seq
   {
    {\theinnerexercise}{\exp_not:V \BODY}
   }
 }
\NewDocumentEnvironment{solution*}{}
 {
  \phantomsection\label{dvvv_ \theinnerexercise _reverse_label}
  \cs_set:Npx \dvvv_exercise_ref:
   {
    \exp_not:N \hyperref
     [
      dvvv_ \theinnerexercise _label
     ]
     {
      Solution~of~\exp_not:N\ref*{dvvv_ \theinnerexercise _label}
     }
   }
  \innersolution
 }
 {
  \endinnersolution
 }
\NewDocumentCommand{\printsolutions}{}
 {
  \seq_map_inline:Nn \g_dvvv_solution_group_seq
   {
    \dvvv_print_solutions:nn ##1
   }
  \seq_gclear:N \g_dvvv_solution_group_seq
 }

\seq_new:N \g_dvvv_solution_group_seq

\cs_new_protected:Npn \dvvv_print_solutions:nn #1 #2
 {
  \cs_set:Npn \dvvv_exercise_ref:
   {
    \phantomsection\label{dvvv_#1_reverse_label}
    \hyperref[dvvv_#1_label]{Solution~of~\ref*{dvvv_#1_label}}
   }
  \begin{innersolution} #2 \end{innersolution}
 }
\ExplSyntaxOff

\begin{document}

\chapter{Title}

\section{Exercises}

\begin{exercise}
This is an exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is an exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is an exercise.
\end{exercise}

Some optional text in between.

\begin{solution*}
This is a solution.
\end{solution*}

The solution has been printed immediately, because
\texttt{solution*} has been used.

\begin{exercise}
This is another exercise.
\end{exercise}
\begin{solution}
A solution.
\end{solution}

\begin{exercise}
This is yet another exercise.
\end{exercise}
\begin{solution}
Too much.
\end{solution}

\clearpage
\section{Solutions}
\printsolutions

\end{document}

2019 年 3 月更新

xparse2019-03-05 或更高版本发布后,不再需要environ。将代码替换solution

\NewDocumentEnvironment{solution}{+b}
 {
  \seq_gput_right:Nx \g_dvvv_solution_group_seq
   {
    {\theinnerexercise}{ \exp_not:n { #1 } }
   }
 }
 {}

答案2

另一个解决方案是使用tcolorbox。此包提供命令\tcbstartrecording[file]\tcbstoprecording和 ,\tcbinputrecording[file]可用作 OP\hidesolutions\stophidesolutions

Anytcolorbox分为上下两部分。我们可以将上半部分用作练习,下半部分用作解决方案。Optionssavelowerto会创建一个辅助文件,用于保存下半部分。可以使用 option 保存此文件以供日后使用record。并且可以使用 将这些记录的片段包含到我们的文档中\tcbinputrecording

下一个代码显示了基于tcolorbox文档中“7.3 示例:练习”和“13.9 创建 LaTeX 练习”中的代码的示例。

我还在tcblisting问题和解决方案中添加了方框,因为它是作为对 NewEnviron、\BODY 和 lstlisting在我发布之前它就被关闭了。我认为对于这个问题来说也是有效的。

代码包含一些注释,我希望这些注释能够帮助理解它的工作原理

\documentclass{article}

\usepackage{lipsum}
\usepackage[most]{tcolorbox}
\usepackage{hyperref}

\NewTColorBox[auto counter,number within=section]{exercise}{+O{}}{%
        enhanced, colframe=green!20!black, colback=yellow!10!white, 
        coltitle=green!40!black, fonttitle=\bfseries,
        title={Exercise~\thetcbcounter:},
        label={exercise@\thetcbcounter},
        attach title to upper=\quad,
        after upper={\par\hfill\textcolor{green!40!black}%
             {\itshape Solution on page~\pageref{solution@\thetcbcounter}}},
        lowerbox=ignored,
        savelowerto=solutions/exercise-\thetcbcounter.tex,
        record={\string\solution{\thetcbcounter}%
               {solutions/exercise-\thetcbcounter.tex}},
        #1}

\NewTotalTColorBox{\solution}{mm}{%
        enhanced, colframe=red!20!black, colback=yellow!10!white,             
        coltitle=red!40!black, fonttitle=\bfseries,
        title={Solution of Exercise~\ref{exercise@#1} on page~\pageref{exercise@#1}:},
        phantomlabel={solution@#1},
        attach title to upper=\par,
        }{\input{#2}}

\tcbset{no solution/.style={no recording,after upper=}}

\newtcblisting{mylisting}{listing only}

\begin{document}
\section{Some problems}

% We start to record all `tcblower` parts in file `file1` for later provessing 
\tcbstartrecording[file1]

%Every exercise box contains an upper part which is processed and
%printed and a lower (solution) which printing is delayed.
%
\begin{exercise}
Type some nice code
\begin{mylisting}
This is my
first listing
\end{mylisting}
\tcblower       %<--------- Here upper part finishes and lower starts
The solution could be:
\begin{mylisting}
This is the solution
for the first listing problem
\end{mylisting}
\end{exercise}

\tcbstoprecording  %<---- recording solutions in `file1` is finished. 

% Recording mechanism has been stopped. Solutions are printed after
% upper part. 
\begin{exercise}[lowerbox=visible]  %<--- lowerbox is `invisible` in `exercise` boxes
Type some nice code
\tcblower
The solution could be:
\begin{mylisting}
My code 2
\end{mylisting}
\end{exercise}

% another file will continue recording solutions
\tcbstartrecording[file2]

\begin{exercise}
Type some nice code
\tcblower
The solution could be:
\begin{mylisting}
My code 3
\end{mylisting}
\end{exercise}

\tcbstoprecording

\section{Some solutions to previous problems}

%previous recorded files with solutions are processed and printed
\tcbinputrecords[file1]
\tcbinputrecords[file2]

\end{document}

之前的代码只是一个起点。一些细节,比如未记录解决方案的引用或样式,必须解决。无论如何,结果如下所示:

在此处输入图片描述

相关内容