![使用 \declaretheoremstyle 为练习创建解决方案标签](https://linux22.com/image/442689/%E4%BD%BF%E7%94%A8%20%5Cdeclaretheoremstyle%20%E4%B8%BA%E7%BB%83%E4%B9%A0%E5%88%9B%E5%BB%BA%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E6%A0%87%E7%AD%BE.png)
我正在写一本书,其中的练习散布在正文各处,每章末尾都给出了解决方案。
我想要的布局如下:
课文中介绍了一个exercise
环境。本练习的答案稍后将在本章末尾的“练习答案”部分中出现。
此外,环境末尾exercise
还会有一个页面引用,指向标有其解决方案的页面。
一个直观的例子(人为制作)如下:
本章的最后一部分是
我假设“第 xx 页的解决方案”字符串将是命令的postfoothook
键的值,但我不知道如何在该值中额外插入 。\declaretheoremstyle
thmtools
label
也许我走得太远了,但我也愿意使用其中一种方法来做到这一点exercise
包 (xsim
看起来最有希望)。我只是还没有偶然发现过这种确切的布局。
编辑:
因为最终的文档要在 LyX 中排版,所以我认为实现我的目标的更好方法是不使用xsim
,因为对于参考,LyX 可以使用 LaTeX 的基本构建基石 -label
及其pageref
朋友。
我认为插入适当的代码postfoothook
就heading
可以完成这项工作,但这是我寻求帮助的地方:
练习和解决方案的标签采用以下格式:
ex:ch1:ratio-of-odd-numbers
<->sol:ex:ch1:ratio-of-odd-numbers
ex:ch2:rolling-n-sided-die
<->sol:ex:ch2:rolling-n-sided-die
ex:ch2:the-hotel-problem
<->sol:ex:ch2:the-hotel-problem
我需要的是在练习中引用里面sol:⟨the exrecise label⟩
,并在解决方案的标题中postfoothook
引用。⟨the exrecise label⟩
\begin{exercise}\label{ex:ch1:every-prime}
blah blah
\end{exercise}
其解决方案的格式为
\begin{solution}\label{sol:ex:ch1:every-prime}
Solution to blah blah.
\end{solution}
- 为了生成参考“第 xx 页的解决方案”,我需要连接
sol:
以⟨the exrecise label⟩
生成
\pageref{sol:⟨the exrecise label⟩}
其中,在此示例中⟨the exrecise label⟩
为ex:every-prime
(创建\pageref{sol:ex:ch1:every-prime}
)。
- 为了生成标题“练习 xx 的解决方案”,我需要从标签
sol:
中删除部分solution
以生成\ref{⟨the exrecise label⟩}
,因此在这个例子中它将是\ref{ex:ch1:every-prime}
。
有什么帮助吗?
一位 MWE 表示:
\documentclass{book}
\usepackage{fontspec,hyperref,amsthm,thmtools}
%%
\declaretheoremstyle[
postfoothook = \rightline{Solution on page \pageref{sol:⟨the exrecise label⟩}
]{exercise}
\declaretheorem[style=exercise]{exercise}
\declaretheoremstyle[
heading = Solution to Exercise \ref{⟨the solution label without "sol:"⟩},
numbered=no,
]{solution}
\declaretheorem[style=solution]{solution}
%%
\begin{document}
\chapter{Prime numbers}
Lorem ipsum
\section{Dolor sit amet}
Consectetur adipiscing elit.
\begin{exercise}[Euclid]{ex:ch1:every-prime}
Prove that for every prime $p$, there is a prime $p^\prime > p$. In particular, the list of primes, $2, 3, 5, 7, \ldots$ , is infinite.
\end{exercise}
\section{Solution to exercises}
\begin{solution}\label{sol:ex:ch1:every-prime}
The proof is straight forward. First note that...
\end{solution}
\end{document}
编辑2
作为对 muzimuzhi Z 答案的跟进,我还想在我的书中添加一个“无解练习”。这个环境可能被命名,我希望它与接受的答案中定义的环境exercise-nosol
共享相同的计数器。exercise
怎么做?
也就是说,如何定义两个环境(exercise
with xsim
,exercise-nosol
with thmtool
)使得它们共享同一个计数器?
我定义它thmtools
如下:
\declaretheoremstyle[
postfoothook = \rightline{(No Solution) $\blacktriangleleft$}
]{exercise-nosol}
\declaretheorem[name=Exercise,numberwithin=chapter,style=exercise]{exercise}
答案1
xsim
基于包手册中所示的“示例 5:问题和答案之间的交叉引用”的尝试。
\documentclass{article}
\usepackage{amssymb}
\usepackage{xsim,lipsum,hyperref}
\hypersetup{colorlinks}
\DeclareExerciseHeadingTemplate{custom}
{\section{\XSIMexpandcode{\XSIMtranslate{default-heading}}}}
\DeclareExerciseEnvironmentTemplate{custom}
{%
\IfInsideSolutionTF
{\label{sol:\ExerciseID}}
{\label{ex:\ExerciseID}}%
\paragraph*
{%
\XSIMmixedcase{\GetExerciseName}%
\IfInsideSolutionTF
{
to \GetExerciseParameter{exercise-name}%
~\GetExerciseProperty{counter}%
~(From Page~\pageref{ex:\ExerciseID})
}
{%
~\GetExerciseProperty{counter}%
\GetExercisePropertyT{subtitle}{~(\PropertyValue)}
}%
}%
}
{%
\IfInsideSolutionF
{\par\leavevmode\hfill
Solution on page~\pageref{sol:\ExerciseID}~$\blacktriangleleft$}%
}
\xsimsetup{
exercise/template = custom ,
solution/template = custom ,
print-solutions/headings-template = custom
}
\begin{document}
\section{Exercises}
\begin{exercise}[subtitle=title]
\lipsum[1][2]
\end{exercise}
\begin{solution}
\lipsum[1][2]
\end{solution}
\begin{exercise}[subtitle=second title]
\lipsum[4]
\end{exercise}
\begin{solution}
\lipsum[4]
\end{solution}
\clearpage
\printsolutions
\end{document}
更新:支持无解练习
为了避免可能出现的不兼容问题,这里xsim
仅进行一次尝试。
\IfSolutionEmptyTF
提供了一个使用xsim
内部的新命令\xsim_attribute_get:nn
。这可能不是最可靠的方法。
我试过xsim
,\IfExistSolutionTF
但似乎没有像我预期的那样工作。也可能是因为一个xsim
问题(见cgnieder/xsim#90
),目前你必须为每个无解练习提供一个空的解决方案环境,例如
\begin{solution} % no empty lines in env contents
\end{solution}
完整示例
\documentclass{article}
\usepackage{amssymb}
\usepackage{xsim,lipsum,hyperref}
\hypersetup{colorlinks}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_if_empty:nTF {e}
\NewExpandableDocumentCommand{\IfSolutionEmptyTF}{}
{
\tl_if_empty:eTF
{
\exp_args:Ne \xsim_attribute_get:nn
{exercise!\ExerciseID} {solution-body}
}
}
\ExplSyntaxOff
\DeclareExerciseHeadingTemplate{custom}
{\section{\XSIMexpandcode{\XSIMtranslate{default-heading}}}}
\DeclareExerciseEnvironmentTemplate{custom-exercise}
{%
\label{ex:\ExerciseID}%
\paragraph*
{%
% typset "Exercise <num> (<subtitle>)"
\XSIMmixedcase{\GetExerciseName}%
~\GetExerciseProperty{counter}%
\GetExercisePropertyT{subtitle}{~(\PropertyValue)}
}%
}
{%
\par\leavevmode\hfill
% typeset "Solution on page <page>" or "(No solution)"
\ifcsname r@sol:\ExerciseID\endcsname
Solution on page~\pageref{sol:\ExerciseID}%
\else
(No Solution)%
\fi
~$\blacktriangleleft$%
}
\DeclareExerciseEnvironmentTemplate{custom-solution}
{%
\IfSolutionEmptyTF{}
{
\label{sol:\ExerciseID}
\paragraph*
{%
\XSIMmixedcase{\GetExerciseName}
to \GetExerciseParameter{exercise-name}%
~\GetExerciseProperty{counter}%
~(From Page~\pageref{ex:\ExerciseID})
}%
}
}{%
\par
}
\xsimsetup{
exercise/template = custom-exercise ,
solution/template = custom-solution ,
print-solutions/headings-template = custom
}
\begin{document}
\section{Exercises}
\begin{exercise}[subtitle=title]
\lipsum[1][2]
\end{exercise}
\begin{solution}
\lipsum[1][2]
\end{solution}
\begin{exercise}[subtitle=no solution]
\lipsum[3][1] aaa
\end{exercise}
% You still need to provide an empty solution environment.
\begin{solution}
\end{solution}
\begin{exercise}[subtitle=third title]
\lipsum[4][1-3]
\end{exercise}
\begin{solution}
\lipsum[4][4-6]
\end{solution}
\begin{exercise}[subtitle=fourth title]
\lipsum[4][1-3]
\end{exercise}
\begin{solution}
\lipsum[4][4-6]
\end{solution}
\clearpage
\printsolutions
\end{document}
答案2
一种方法是使用exsheets
包,它允许使用命令将解决方案方便地放置在章节末尾\printsolutions[chapter]
。我们可以使用提供的标签标记每个问题(和解决方案)以进行页码编号和链接\CurrentQuestionID
。我选择标记问题Q:\CurrentQuestionID
和答案A:\CurrentQuestionID
。
为了设计与您的示例类似的问题和解决方案,我们定义了一个新命令\problem
,它接收并将其<subtitle><question text><solution>
传递给和环境并处理基本格式。exsheets
question
solution
显然,该文件需要编译两次才能获得页面引用。
\documentclass{book}
\usepackage{wasysym}
\usepackage[colorlinks=true]{hyperref}
\usepackage{exsheets}
\SetupExSheets{headings = runin}
\newcommand\problem[3]{
\begin{question}
\textbf{(#1)} \label{Q:\CurrentQuestionID} #2
\begin{flushright} Solution on page \pageref{A:\CurrentQuestionID} \LEFTarrow \end{flushright}
\end{question}
\begin{solution}[name = Solution to exercise]
\textbf{(From Page \pageref{Q:\CurrentQuestionID})}
\label{A:\CurrentQuestionID} #3
\end{solution}
}
\begin{document}
\chapter{Prime Numbers}
\section{Dolor sit amet}
\problem{Euclid}{
Prove that for every prime $p$, there is a prime $p^\prime > p$. In particular, the list of primes, $2, 3, 5, 7, \ldots$ , is infinite.
}{The proof is straight forward. First note that...}
\problem{Fermat}{
$a^n+b^n=c^n$}{The proof is too large to fit on this page}
\section{Solutions}
\printsolutions[chapter]
\end{document}
这在 LyX 中是可行的。在下面Documents>Settings>LaTeX Preamble
输入序言,然后在该设置窗格中更改documentclass
为书籍(或带有章节的其他内容)。然后,您只需\problem
在 LyX 中输入 LaTeX 代码,如下所示。输出与上面相同。
答案3
含exercise
包装:
\documentclass{book}
\usepackage{fontspec,amsthm,thmtools}
\usepackage{amsmath, amssymb}
\usepackage{chngcntr}
\usepackage{etoolbox}
\usepackage{mwe}% <--- for testing purpose only
\usepackage{xcolor}
\usepackage[pdfborder={0 0 0}]{hyperref}% you must load it before the exercise package
\usepackage{exercise}
%\counterwithin{Exercise}{chapter} This line if you want exercise 1.1, 1.2, etc. in chapter 1
%\counterwithin{Answer}{chapter}
\renewcounter{Exercise}[chapter]
\renewcommand{\ExerciseName}{Exercise}
\renewcommand{\ExerciseHeader}{\noindent\bfseries\ExerciseName\ \ExerciseHeaderNB\ (\ExerciseTitle)}
\renewcommand{\AnswerName}{Solution to exercise}
\renewcommand{\AnswerHeader}{\noindent\bfseries\AnswerName\ \ExerciseHeaderNB\ (From Page \textcolor{red}{\pageref{\AnswerRef}})}
\setlength{\ExerciseSkipBefore}{\baselineskip}
\setlength{\AnswerSkipBefore}{\baselineskip}
\setlength{\ExerciseSkipAfter}{0pt}
\setlength{\AnswerSkipAfter}{\baselineskip}
\AfterEndEnvironment{Exercise}{\hspace{\fill}
Solution on page \textcolor{red}{\pageref{\ExerciseLabel-Answer}} $\blacktriangleleft$\vspace{\baselineskip}\par}
\begin{document}
\chapter{Prime numbers}
Lorem ipsum
\section{Dolor sit amet}
Consectetur adipiscing elit.
\begin{Exercise}[title={Euclid},label={ex:ch1:every-prime}]
Prove that for every prime $p$, there is a prime $p^\prime > p$. In particular, the list of primes, $2, 3, 5, 7, \ldots$ , is infinite.
\end{Exercise}
\blindtext% <--- for testing purpose only
\begin{Exercise}[title={Another one},label={ex:ch1:second}]
Prove that ducks are the best.
\end{Exercise}
\blindtext% <--- for testing purpose only
\section{Solution to Exercises}
\begin{Answer}[ref=ex:ch1:every-prime]
The proof is straight forward. First note that...
\end{Answer}
\blindtext% <--- for testing purpose only
\begin{Answer}[ref=ex:ch1:second]
The proof is straight forward. First note that...
\end{Answer}
\blindtext% <--- for testing purpose only
\chapter{Second chapter}
Lorem ipsum
\section{A section}
Consectetur adipiscing elit.
\begin{Exercise}[title={An exercise},label={ex:ch2:an-ex}]
Prove that something is true.
\end{Exercise}
\blindtext% <--- for testing purpose only
\begin{Exercise}[title={Another one again},label={ex:ch2:second}]
Prove that ducks are the best of all.
\end{Exercise}
\section{Solution to Exercises}
\blindtext% <--- for testing purpose only
\begin{Answer}[ref=ex:ch2:an-ex]
The proof of the first.
\end{Answer}
\blindtext% <--- for testing purpose only
\begin{Answer}[ref=ex:ch2:second]
The proof of the second.
\end{Answer}
\end{document}
如果答案部分仅包含答案,您也可以使用answerdelayed
并打印所有答案\shipoutAnswer
:
\documentclass{book}
\usepackage{fontspec,amsthm,thmtools}
\usepackage{amsmath, amssymb}
\usepackage{chngcntr}
\usepackage{etoolbox}
\usepackage{mwe}% <--- for testing purpose only
\usepackage{xcolor}
\usepackage[pdfborder={0 0 0}]{hyperref}% you must load it before the exercise package
\usepackage[answerdelayed, lastexercise]{exercise}
%\counterwithin{Exercise}{chapter} This line if you want exercise 1.1, 1.2, etc. in chapter 1
%\counterwithin{Answer}{chapter}
\renewcounter{Exercise}[chapter]
\renewcommand{\ExerciseName}{Exercise}
\renewcommand{\ExerciseHeader}{\noindent\bfseries\ExerciseName\ \ExerciseHeaderNB\ (\ExerciseTitle)}
\renewcommand{\AnswerName}{Solution to exercise}
\renewcommand{\AnswerHeader}{\noindent\bfseries\AnswerName\ \ExerciseHeaderNB\ (From Page \textcolor{red}{\pageref{\AnswerRef}})}
\setlength{\ExerciseSkipBefore}{\baselineskip}
\setlength{\AnswerSkipBefore}{\baselineskip}
\setlength{\ExerciseSkipAfter}{0pt}
\setlength{\AnswerSkipAfter}{\baselineskip}
\AfterEndEnvironment{Exercise}{\hspace{\fill}
Solution on page \textcolor{red}{\pageref{\ExerciseLabel-Answer}} $\blacktriangleleft$}
\begin{document}
\chapter{Prime numbers}
Lorem ipsum
\section{Dolor sit amet}
Consectetur adipiscing elit.
\begin{Exercise}[title={Euclid},label={ex:ch1:every-prime}]
Prove that for every prime $p$, there is a prime $p^\prime > p$. In particular, the list of primes, $2, 3, 5, 7, \ldots$ , is infinite.
\end{Exercise}
\begin{Answer}[ref=\ExerciseLabel]
The proof is straight forward. First note that...
\end{Answer}
\blindtext% <--- for testing purpose only
\begin{Exercise}[title={Another one},label={ex:ch1:second}]
Prove that ducks are the best.
\end{Exercise}
\begin{Answer}[ref=\ExerciseLabel]
The proof is straight forward. First note that...
\end{Answer}
\blindtext% <--- for testing purpose only
\section{Solution to Exercises}
\shipoutAnswer
\chapter{Second chapter}
Lorem ipsum
\section{A section}
Consectetur adipiscing elit.
\begin{Exercise}[title={An exercise},label={ex:ch2:an-ex}]
Prove that something is true.
\end{Exercise}
\begin{Answer}[ref=\ExerciseLabel]
The proof of the first.
\end{Answer}
\blindtext% <--- for testing purpose only
\begin{Exercise}[title={Another one again},label={ex:ch2:second}]
Prove that ducks are the best of all.
\end{Exercise}%
\begin{Answer}[ref=\ExerciseLabel]
The proof of the second.
\end{Answer}
\section{Solution to Exercises}
\shipoutAnswer
\end{document}