我正在尝试使用 xsim 来使用两种练习类型“练习”和“问题”。这两种练习类型都将用于在书的不同部分显示“练习”和“问题”,并在书的末尾分别显示它们的答案。@cgnieder 描述了如何使用练习类型“练习”来实现所需的目的这里。我采用了如下代码:
\DeclareExerciseEnvironmentTemplate{exercise-temp}{%
\par\noindent
\textbf{\GetExerciseProperty{counter}}%
\GetExercisePropertyT{subtitle}{ \textit{#1}} %
}{\par}
\newcommand\printsectionexercises{%
\ForEachUsedExerciseByType{%
\ifnum\ExercisePropertyGet{exercise}{##2}{chapter-value}=\value{chapter}
\ifnum\ExercisePropertyGet{exercise}{##2}{section-value}=\value{section}
\XSIMprint{exercise}{exercise}{##2}%
\fi
\fi
}%
}
\newcommand\printexercisesolutions{%
\def\currentchapter{}%
\def\currentsection{}%
\def\lastchapter{}%
\def\lastsection{}%
\ForEachUsedExerciseByType{%
\let\lastchapter\currentchapter
\let\lastsection\currentsection
\edef\currentchapter{\ExercisePropertyGet{exercise}{##2}{chapter-value}}%
\edef\currentsection{\ExercisePropertyGet{exercise}{##2}{section-value}}%
\ifx\lastchapter\currentchapter\else
\section*{Chapter \ExercisePropertyGet{exercise}{##2}{chapter}}
\fi
\ifx\lastsection\currentsection\else
\subsection*{Exercise \ExercisePropertyGet{exercise}{##2}{section}}
\fi
\XSIMprint{solution}{exercise}{##2}%
}%
}
\xsimsetup{
exercise/template = exercise-temp ,
solution/template = exercise-temp ,
exercise/within = section ,
exercise/the-counter = \arabic{exercise}. ,
exercise/print = false
}
要打印“练习”,我使用
\subsection*{Exercise \thesection}
\printsectionexercises
为了给书末的所有练习提供“答案”,我使用
\printexercisesolutions
上述代码给出了所需的结果。
接下来,我尝试将上述代码用于其他 ExerciseType“问题”,如下所示:
\DeclareExerciseEnvironmentTemplate{question-temp}{%
\par\noindent
\textbf{\GetExerciseProperty{counter}}%
\GetExercisePropertyT{subtitle}{ \textit{#1}} %
}{\par}
\DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = \XSIMtranslate{Question} ,
exercises-name = \XSIMtranslate{Questions} ,
solution-name = \XSIMtranslate{Answer} ,
solutions-name = \XSIMtranslate{Answers} ,
exercise-template = question-temp ,
solution-template = question-temp ,
exercise-heading = \subsection* ,
solution-heading = \subsection*
}
\newcommand{\printsectionquestions}{%
\ForEachUsedExerciseByType{%
\ifnum\ExercisePropertyGet{question}{##2}{chapter-value}=\value{chapter}
\ifnum\ExercisePropertyGet{question}{##2}{section-value}=\value{section}
\XSIMprint{question}{question}{##2}%
\fi
\fi
}%
}
\newcommand{\printquestionsolutions}{%
\def\currentchapter{}%
\def\currentsection{}%
\def\lastchapter{}%
\def\lastsection{}%
\ForEachUsedExerciseByType{%
\let\lastchapter\currentchapter
\let\lastsection\currentsection
\edef\currentchapter{\ExercisePropertyGet{question}{##2}{chapter-value}}%
\edef\currentsection{\ExercisePropertyGet{question}{##2}{section-value}}%
\ifx\lastchapter\currentchapter\else
\section*{Chapter \ExercisePropertyGet{question}{##2}{chapter}}
\fi
\ifx\lastsection\currentsection\else
\subsection*{Question \ExercisePropertyGet{question}{##2}{section}}
\fi
\XSIMprint{answer}{question}{##2}%
}%
}
\xsimsetup{
exercise/template = question-temp ,
solution/template = question-temp ,
exercise/within = section ,
exercise/the-counter = \arabic{question}. ,
exercise/print = false
}
为了打印“问题”,我使用
\subsection*{Question \thesection}
\printsectionquestions
为了在最后打印出问题的“答案”,我使用
\printquestionsolutions
但是上述“问题”代码并没有给出与“练习”相应代码类似的结果。
问题:“问题”的编码结果与“练习”的编码结果有以下两点不同:
如果有人能帮助解决上述问题,我将不胜感激。我是乳胶新手,所以请多多包涵。
ExerciseType 'Question' 的完整代码如下:
\documentclass[fontsize=11pt]{book}
\usepackage{xsim}
%%For 'Questions'%%
\DeclareExerciseEnvironmentTemplate{question-temp}{%
\par\noindent
\textbf{\GetExerciseProperty{counter}}%
\GetExercisePropertyT{subtitle}{ \textit{#1}} %
}{\par}
\DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = \XSIMtranslate{Question} ,
exercises-name = \XSIMtranslate{Questions} ,
solution-name = \XSIMtranslate{Answer} ,
solutions-name = \XSIMtranslate{Answers} ,
exercise-template = question-temp ,
solution-template = question-temp ,
exercise-heading = \subsection* ,
solution-heading = \subsection*
}
\newcommand{\printsectionquestions}{%
\ForEachUsedExerciseByType{%
\ifnum\ExercisePropertyGet{question}{##2}{chapter-value}=\value{chapter}
\ifnum\ExercisePropertyGet{question}{##2}{section-value}=\value{section}
\XSIMprint{question}{question}{##2}%
\fi
\fi
}%
}
\newcommand{\printquestionsolutions}{%
\def\currentchapter{}%
\def\currentsection{}%
\def\lastchapter{}%
\def\lastsection{}%
\ForEachUsedExerciseByType{%
\let\lastchapter\currentchapter
\let\lastsection\currentsection
\edef\currentchapter{\ExercisePropertyGet{question}{##2}{chapter-value}}%
\edef\currentsection{\ExercisePropertyGet{question}{##2}{section-value}}%
\ifx\lastchapter\currentchapter\else
\section*{Chapter \ExercisePropertyGet{question}{##2}{chapter}}
\fi
\ifx\lastsection\currentsection\else
\subsection*{Question \ExercisePropertyGet{question}{##2}{section}}
\fi
\XSIMprint{answer}{question}{##2}%
}%
}
\xsimsetup{
exercise/template = question-temp ,
solution/template = question-temp ,
exercise/within = section ,
exercise/the-counter = \arabic{question}. ,
exercise/print = false
}
\begin{document}
\mainmatter
\chapter{Chapter on Cat}
\section{Cat-1}
SOME TEXT...
\begin{question}
Question 1 in Section 1.1 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 1 in Section 1.1 in Chapter 1
\end{answer}
\begin{question}
Question 2 in Section 1.1 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 2 in Section 1.1 in Chapter 1
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\section{Cat-2}
SOME TEXT...
\begin{question}
Question 1 in Section 1.2 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 1 in Section 1.2 in Chapter 1
\end{answer}
\begin{question}
Question 2 in Section 1.2 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 2 in Section 1.2 in Chapter 1
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\chapter{Chapter on Dog}
\section{Dog-1}
SOME TEXT...
\begin{question}
Question 1 in Section 2.1 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 1 in Section 2.1 in Chapter 2
\end{answer}
\begin{question}
Question 2 in Section 2.1 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 2 in Section 2.1 in Chapter 2
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\section{Dog-2}
SOME TEXT...
\begin{question}
Question 1 in Section 2.2 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 1 in Section 2.2 in Chapter 2
\end{answer}
\begin{question}
Question 2 in Section 2.2 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 2 in Section 2.2 in Chapter 2
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\chapter*{\underline{Answers to Questions}}
\printquestionsolutions
\end{document}
编辑: 最后,我想要在同一个文件中使用“锻炼”和“问题”实现如下效果:
答案1
提供的一些配置xsim
可能会令人费解。
第一的exercise/print
中所使用的选项\xsimsetup{exercise/print=false}
是针对每个锻炼类型的。这意味着的一般形式exercise/print
是<env name>/print
。因此,要针对锻炼类型设置question
,您需要设置
\xsimsetup{
question/template = question-temp ,
answer/template = question-temp ,
question/within = section ,
question/the-counter = \arabic{question}. ,
question/print = false
}
这解释了问题 1
- 问题集的标题(例如,以下屏幕截图中的“问题 1.1”)出现在问题集下方,而它应该出现在上方:
因为在原始设置下\xsimsetup{exercise/print=false}
,只有类型的练习exercise
不会被打印,problem
默认情况下,(新)类型的练习仍会打印。另请参阅包手册(v0.21,2022/02/12),
8.2. 环境选项和钩子
对于每种练习类型,两种环境都有以下选项,环境的名称是选项的模块名称(此处使用“练习”类型):
因此,问题 1 的实际发生情况是,problem
环境被立即打印,并且\printsectionquestions
什么都没有打印。
更令人费解的是, 的第一个强制参数\XSIMprint
必须是“exercise”或“solution”之一。因此\XSIMprint{answer}{question}{##2}
不会打印任何内容,也不会抛出任何错误。
这解释了问题2。
完整且更新的示例
\documentclass[fontsize=11pt]{book}
\usepackage{xsim}
%%For 'Questions'%%
\DeclareExerciseEnvironmentTemplate{question-temp}{%
\par\noindent
\textbf{\GetExerciseProperty{counter}}%
\GetExercisePropertyT{subtitle}{ \textit{#1}} %
}{\par}
\DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = \XSIMtranslate{Question} ,
exercises-name = \XSIMtranslate{Questions} ,
solution-name = \XSIMtranslate{Answer} ,
solutions-name = \XSIMtranslate{Answers} ,
exercise-template = question-temp ,
solution-template = question-temp ,
exercise-heading = \subsection* ,
solution-heading = \subsection*
}
\newcommand{\printsectionquestions}{%
% ##1 type, ##2 id, ...
\ForEachUsedExerciseByType{%
\ifstrequal{question}{##1}{%
\ifnum\ExercisePropertyGet{##1}{##2}{chapter-value}=\value{chapter}\relax
\ifnum\ExercisePropertyGet{##1}{##2}{section-value}=\value{section}\relax
\XSIMprint{exercise}{##1}{##2}%
\fi
\fi
}{}%
}%
}
\newcommand{\printquestionsolutions}{%
\def\currentchapter{}%
\def\currentsection{}%
\def\lastchapter{}%
\def\lastsection{}%
\ForEachUsedExerciseByType{%
\ifstrequal{question}{##1}{%
\let\lastchapter\currentchapter
\let\lastsection\currentsection
\edef\currentchapter{\ExercisePropertyGet{##1}{##2}{chapter-value}}%
\edef\currentsection{\ExercisePropertyGet{##1}{##2}{section-value}}%
\ifx\lastchapter\currentchapter\else
\section*{Chapter \ExercisePropertyGet{##1}{##2}{chapter}}
\fi
\ifx\lastsection\currentsection\else
\subsection*{Question \ExercisePropertyGet{##1}{##2}{section}}
\fi
\XSIMprint{solution}{##1}{##2}%
}{}%
}%
}
\xsimsetup{
question/template = question-temp ,
answer/template = question-temp ,
question/within = section ,
question/the-counter = \arabic{question}. ,
question/print = false
}
\begin{document}
\mainmatter
\chapter{Chapter on Cat}
\section{Cat-1}
SOME TEXT...
\begin{question}
Question 1 in Section 1.1 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 1 in Section 1.1 in Chapter 1
\end{answer}
MORE TEXT...
\begin{question}
Question 2 in Section 1.1 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 2 in Section 1.1 in Chapter 1
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\section{Cat-2}
SOME TEXT...
\begin{question}
Question 1 in Section 1.2 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 1 in Section 1.2 in Chapter 1
\end{answer}
MORE TEXT...
\begin{question}
Question 2 in Section 1.2 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 2 in Section 1.2 in Chapter 1
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\chapter{Chapter on Dog}
\section{Dog-1}
SOME TEXT...
\begin{question}
Question 1 in Section 2.1 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 1 in Section 2.1 in Chapter 2
\end{answer}
\begin{question}
Question 2 in Section 2.1 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 2 in Section 2.1 in Chapter 2
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\section{Dog-2}
SOME TEXT...
\begin{question}
Question 1 in Section 2.2 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 1 in Section 2.2 in Chapter 2
\end{answer}
\begin{question}
Question 2 in Section 2.2 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 2 in Section 2.2 in Chapter 2
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\chapter*{\underline{Answers to Questions}}
\printquestionsolutions
\end{document}
更新:同时使用两种锻炼类型
除了概括\printSectionExerEnvsOfType
和之外\printSoluEnvsOfType
,还请注意\def\lastsection{}
在里面添加的\ifx\lastchapter\currentchapter\else...\fi
,在,即我前面例子中\printSoluEnvsOfType
的广义形式。\printquestionsolutions
\documentclass[fontsize=11pt]{book}
\usepackage{xsim}
%%For 'Questions'%%
\DeclareExerciseEnvironmentTemplate{question-temp}{%
\par\noindent
\textbf{\GetExerciseProperty{counter}}%
\GetExercisePropertyT{subtitle}{ \textit{#1}} %
}{\par}
\DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = \XSIMtranslate{Question} ,
exercises-name = \XSIMtranslate{Questions} ,
solution-name = \XSIMtranslate{Answer} ,
solutions-name = \XSIMtranslate{Answers} ,
exercise-template = question-temp ,
solution-template = question-temp ,
exercise-heading = \subsection* ,
solution-heading = \subsection*
}
\newcommand{\printSectionExerEnvsOfType}[1]{%
% ##1 type, ##2 id, ...
\ForEachUsedExerciseByType{%
\ifstrequal{#1}{##1}{%
\ifnum\ExercisePropertyGet{##1}{##2}{chapter-value}=\value{chapter}\relax
\ifnum\ExercisePropertyGet{##1}{##2}{section-value}=\value{section}\relax
% \texttt{<##1><##2>}\par
\XSIMprint{exercise}{##1}{##2}%
\fi
\fi
}{}%
}%
}
\newcommand{\printsectionexercises}{%
\printSectionExerEnvsOfType{exercise}%
}
\newcommand{\printsectionquestions}{%
\printSectionExerEnvsOfType{question}%
}
\newcommand{\printSoluEnvsOfType}[1]{%
\def\currentchapter{}%
\def\currentsection{}%
\def\lastchapter{}%
\def\lastsection{}%
\ForEachUsedExerciseByType{%
\ifstrequal{#1}{##1}{%
\let\lastchapter\currentchapter
\let\lastsection\currentsection
\edef\currentchapter{\ExercisePropertyGet{##1}{##2}{chapter-value}}%
\edef\currentsection{\ExercisePropertyGet{##1}{##2}{section-value}}%
\ifx\lastchapter\currentchapter\else
\section*{Chapter \ExercisePropertyGet{##1}{##2}{chapter}}
\def\lastsection{}%
\fi
\ifx\lastsection\currentsection\else
\subsection*{Question \ExercisePropertyGet{##1}{##2}{section}}
\fi
\XSIMprint{solution}{##1}{##2}%
}{}%
}%
}
\newcommand{\printexercisesolutions}{%
\printSoluEnvsOfType{exercise}%
}
\newcommand{\printquestionsolutions}{%
\printSoluEnvsOfType{question}%
}
\xsimsetup{
% for exercise type 'exercise'
exercise/template = question-temp ,
solution/template = question-temp ,
exercise/within = section ,
exercise/the-counter = \arabic{exercise}. ,
exercise/print = false,
% for exercise type 'question'
question/within = section ,
question/the-counter = \arabic{question}. ,
question/print = false,
}
\begin{document}
\mainmatter
\chapter{Chapter on Cat}
\section{Cat-1}
SOME TEXT...
\begin{exercise}
Exercise 1 in Section 1.1 in Chapter 1
\end{exercise}
\begin{solution}
Solution of Exercise 1 in Section 1.1 in Chapter 1
\end{solution}
MORE TEXT...
\begin{exercise}
Exercise 2 in Section 1.1 in Chapter 1
\end{exercise}
\begin{solution}
Solution of Exercise 2 in Section 1.1 in Chapter 1
\end{solution}
\subsection*{Exercise \thesection}
\printsectionexercises
\section{Cat-2}
SOME TEXT...
\begin{question}
Question 1 in Section 1.2 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 1 in Section 1.2 in Chapter 1
\end{answer}
MORE TEXT...
\begin{question}
Question 2 in Section 1.2 in Chapter 1
\end{question}
\begin{answer}
Answer of Question 2 in Section 1.2 in Chapter 1
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\chapter{Chapter on Dog}
\section{Dog-1}
SOME TEXT...
\begin{exercise}
Exercise 1 in Section 2.1 in Chapter 2
\end{exercise}
\begin{solution}
Solution of Exercise 1 in Section 2.1 in Chapter 2
\end{solution}
\begin{exercise}
Exercise 2 in Section 2.1 in Chapter 2
\end{exercise}
\begin{solution}
Solution of Exercise 2 in Section 2.1 in Chapter 2
\end{solution}
\subsection*{Exercise \thesection}
\printsectionexercises
\section{Dog-2}
SOME TEXT...
\begin{question}
Question 1 in Section 2.2 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 1 in Section 2.2 in Chapter 2
\end{answer}
\begin{question}
Question 2 in Section 2.2 in Chapter 2
\end{question}
\begin{answer}
Answer of Question 2 in Section 2.2 in Chapter 2
\end{answer}
\subsection*{Question \thesection}
\printsectionquestions
\chapter*{\underline{Solutions to Exercises}}
\printexercisesolutions
\chapter*{\underline{Solutions to Questions}}
\printquestionsolutions
\end{document}
试图:更快,\printSectionExerEnvsOfType
更\printSoluEnvsOfType
。
新的循环宏\ForEachUsedExerciseByIDOfType{<type>}{<loop body>}
比这两个宏都更快\ForEachUsedExerciseByID{<loop body>}
,\ForEachUsedExerciseByType{<loop body>}
因为新的循环宏不会循环遍历(所有声明的)练习类型的内部列表。
\ExplSyntaxOn
% #1: type, #2: loop body
\NewDocumentCommand \ForEachUsedExerciseByIDOfType {m +m}
{
\tl_set_eq:NN \XSIMtmp \ExerciseType
\xsim_foreach_exercise_id_of_type:nnn {used} {#1} {#2}
\tl_set_eq:NN \ExerciseType \XSIMtmp
\tl_clear:N \XSIMtmp
}
\xsim_verbose:n
{ Defining~ loop~ macro~ \xsim_foreach_exercise_id_of_type:nnn }
% #1: boolean property, #2: type, #3: loop body
\cs_new_protected:Npn \xsim_foreach_exercise_id_of_type:nnn #1#2#3
{
\cs_set:cn {__xsim_loop_item:nnnnnn} {#3}
\xsim_foreach_exercise_id:n
{
% type, id, boolean property (i.e., used, printed)
\__xsim_deliver_exercise_details:nnn {#2} {##1} {#1}
}
}
\ExplSyntaxOff
\newcommand{\printSectionExerEnvsOfType}[1]{%
% ##1 type, ##2 id, ...
\ForEachUsedExerciseByIDOfType{#1}{%
\ifnum\ExercisePropertyGet{##1}{##2}{chapter-value}=\value{chapter}\relax
\ifnum\ExercisePropertyGet{##1}{##2}{section-value}=\value{section}\relax
\XSIMprint{exercise}{##1}{##2}%
\fi
\fi
}%
}
\newcommand{\printSoluEnvsOfType}[1]{%
\def\currentchapter{}%
\def\currentsection{}%
\def\lastchapter{}%
\def\lastsection{}%
\ForEachUsedExerciseByIDOfType{#1}{%
\let\lastchapter\currentchapter
\let\lastsection\currentsection
\edef\currentchapter{\ExercisePropertyGet{##1}{##2}{chapter-value}}%
\edef\currentsection{\ExercisePropertyGet{##1}{##2}{section-value}}%
\ifx\lastchapter\currentchapter\else
\section*{Chapter \ExercisePropertyGet{##1}{##2}{chapter}}
\def\lastsection{}%
\fi
\ifx\lastsection\currentsection\else
\subsection*{Question \ExercisePropertyGet{##1}{##2}{section}}
\fi
\XSIMprint{solution}{##1}{##2}%
}%
}