
학생들을 위한 문제 세트를 준비할 수 있도록 연습 패키지와 비슷한 패키지를 직접 작성하려고 합니다. 문서의 적절한 위치에 도달할 때까지 문제 및/또는 솔루션 출력을 연기하고 싶습니다. 나는 일종의 작동하는 것을 가지고 있지만 그것은 다소 투박합니다. 예를 들어, 이것은 꽤 잘 작동합니다:
\usepackage{environ}
\NewEnviron{testb}{\global\expandafter\let\csname bar\endcsname\BODY}
\csname
이름이 동적으로 생성되기 때문에 사용합니다 . 명령이 \BODY
. 예를 들어, 내가 그렇게 하면 \let\bar{\BODY}
라텍스에 동맥류가 있습니다( \bar
단지 {에만 결합됨).
이를 수행하는 다른 방법은 다음과 같습니다.
\NewEnviron{testc}{\global\expandafter\edef\csname foo\endcsname{\BODY}}
이런 종류의 작품입니다. 다음은 작동
\begin{testc}hi\end{testc}
하지만 LaTeX에 동맥류가 발생합니다 \begin{testc}\bf hi\end{testc}
. (오류 메시지는 \incomplete
)입니다. 직접 디버깅을 시도했지만 이해할 수 없는 패키지에 절망적으로 얽혀 있습니다. \tiny
대신에 그렇게 하면 \bf
매우 다른 LaTeX 오류 메시지가 나타납니다.! TeX capacity exceeded, sorry [input stack size=5000].
시작과 끝 사이에 견고함을 유지하면서 나중을 위해 어떻게 과 및 기타 항목 \BODY
의 정교한 조합을 수행할 수 있습니까?\BODY
편집: 아래에 여러 가지 솔루션이 있습니다.
답변1
\unexpanded
에 대한 걱정을 피할 수 있습니다 \protected@xdef
.
\documentclass{article}
\usepackage{environ}
\NewEnviron{exercise}{%
\xdef\savedexercises{%
\unexpanded\expandafter{\savedexercises}%
\noexpand\begin{printedexercise}%
\unexpanded\expandafter{\BODY}%
\noexpand\end{printedexercise}%
}%
}
\newcommand{\printexercises}{%
\savedexercises
\gdef\savedexercises{}%
}
\newcommand{\savedexercises}{}
\newtheorem{printedexercise}{Exercise}
\begin{document}
Here we talk about addition and show that $1+1=2$.
\begin{exercise}
Compute $1+2$
\end{exercise}
Here we talk about integrals.
\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}
Now we can print the exercises.
\printexercises
\end{document}
나는 \newtheorem
단지 예를 들어 사용했습니다.
xparse
2019-03-05 이후 출시 :
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{exercise}{+b}
{
\tl_gput_right:Nn \g_loisel_exercises_tl
{
\begin{printedexercise}
#1
\end{printedexercise}
}
}{}
\NewDocumentCommand{\printexercises}{}
{
\tl_use:N \g_loisel_exercises_tl
\tl_gclear:N \g_loisel_exercises_tl
}
\tl_new:N \g_loisel_exercises_tl
\ExplSyntaxOff
\newtheorem{printedexercise}{Exercise}
\begin{document}
Here we talk about addition and show that $1+1=2$.
\begin{exercise}
Compute $1+2$
\end{exercise}
Here we talk about integrals.
\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}
Now we can print the exercises.
\printexercises
\end{document}
답변2
저장하고 동적으로 항목을 추가 하려면 BODY
두 개의 매크로를 사용하는 것이 가장 좋습니다.
\documentclass{article}
\usepackage{environ}
\NewEnviron{testb}{%
\global\expandafter\let\csname bar\endcsname\BODY
\expandafter\xdef\csname barplus\endcsname{%
\expandafter\noexpand\csname bar\endcsname
\noexpand\bf Hi
}%
}
\begin{document}
\begin{testb}
\bfseries
Hi
\end{testb}
\show\barplus
\end{document}
사용을 피하고 싶다면 \BODY
다음을 사용할 수 있습니다.xparse
\documentclass{article}
\usepackage{xparse}
\NewDocumentEnvironment{testb}{+b}{\expandafter\gdef\csname bar\endcsname{#1}}{}
\begin{document}
\begin{testb}
\bfseries
Hi
\end{testb}
\show\bar
\end{document}
답변3
확장을 트리거하는 요령은 다음을 사용하는 것입니다 \romannumeral
.
\romannumeral
(La)TeX가 변환해야 하는 숫자로 공백 뒤에 오는 일련의 숫자를 함께 모으면 확장 가능한 토큰이 확장됩니다 .
결국 양수가 아닌 숫자가 모이면 변환 결과 (La)TeX는 토큰을 전혀 전달하지 않습니다.
따라서 결국 양수를 찾지 못한다 \romannumeral
는 것을 보장하는 한 많은 확장 작업과 인수 뒤집기 작업을 유발하는 데 훌륭하게 (ab?) 사용할 수 있습니다 .\romannumeral
다음은 변형입니다.에그레그의 답변이는 \romannumeral
and \exchange
대신 \xdef
and 를 사용합니다 \unexpanded
.
\documentclass{article}
\usepackage{environ}
\newcommand\exchange[2]{#2#1}
\NewEnviron{exercise}{%
\expandafter\gdef\expandafter\savedexercises\expandafter{%
\romannumeral0\expandafter\exchange\expandafter{\BODY}{%
\exchange{ }{\expandafter}\savedexercises
\begin{printedexercise}%
}%
\end{printedexercise}%
}%
}
\newcommand{\printexercises}{%
\savedexercises
\gdef\savedexercises{}%
}
\newcommand{\savedexercises}{}
\newtheorem{printedexercise}{Exercise}
\begin{document}
Here we talk about addition and show that $1+1=2$.
\begin{exercise}
Compute $1+2$
\end{exercise}
Here we talk about integrals.
\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}
Now we can print the exercises.
\printexercises
\end{document}
정의할 매크로의 이름을 \csname
.. 로 래핑하려는 경우, 즉 .. 대신을 \endcsname
사용하려는 경우 (La)TeX가 확장 가능한 토큰을 수집하는 동안 확장 가능한 토큰을 수행한다는 사실을 활용할 수 있습니다. 제어 시퀀스 토큰의 이름을 지정하고 이에 따라 일치하는 항목을 검색합니다 .\csname savedexercises\endcsname
\savedexercises
\csname
\endcsname
\documentclass{article}
\usepackage{environ}
\newcommand\exchange[2]{#2#1}
\NewEnviron{exercise}{%
\expandafter\gdef\csname savedexercises\expandafter\endcsname\expandafter{%
\romannumeral0\expandafter\exchange\expandafter{\BODY}{%
\exchange{ }{\expandafter\expandafter\expandafter}\csname savedexercises\endcsname
\begin{printedexercise}%
}%
\end{printedexercise}%
}%
}
\newcommand{\printexercises}{%
\csname savedexercises\endcsname
\expandafter\gdef\csname savedexercises\endcsname{}%
}
\expandafter\newcommand\expandafter{\csname savedexercises\endcsname}{}
\newtheorem{printedexercise}{Exercise}
\begin{document}
Here we talk about addition and show that $1+1=2$.
\begin{exercise}
Compute $1+2$
\end{exercise}
Here we talk about integrals.
\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}
Now we can print the exercises.
\printexercises
\end{document}
\printexercises
지금까지 제시된 접근 방식으로는 임의의 장소에서 운동을 수행하는 데 사용할 수 없습니다 . 소스에서 연습 환경 뒤의 위치에 해당하는 문서 위치에서만 연습이 발생하도록 할 수 있습니다.
아마도 .aux 파일에서 매크로를 정의하기 위해 verbatim-catcode-régime 아래에서 다시 읽는 방식으로 .aux 파일에 확장되지 않은 쓰기를 위해 verbatim-catcode-régime 아래에서 내용을 읽는 환경일 것입니다. 에 적용될 것이므로 - - 메커니즘 또는 축약된 내용에 대한 -메커니즘을 \scantokens
일종의 재구현하면 전체 문서에서 연습문제를 인쇄할 수 있게 만들 수 있습니다.\label
\ref
\tableofcontents
그러한 메커니즘을 구현하는 것은 좋은 도전이 될 수 있습니다. 그러나 이를 전혀 고려하기 전에 의도된 사용법과 원하는 "사용자 인터페이스"에 대한 정확한 정보가 필요합니다. 즉, 어떤 방식으로 지정할 수 있는지 등을 추가로 지정할 수 있습니다.
답변4
을 사용하는 또 다른 변형은 콘텐츠를 filecontentsdef v1.4
지원합니다 verbatim
(필요한 경우).
\documentclass{article}
\usepackage{filecontentsdef,pgffor}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\newtheorem{exercise}{Exercise}
% savedexercise
\newcounter{exeNr}
\newenvironment{savedexercise}
{\stepcounter{exeNr}%
\begingroup
\filecontentsdefmacro{exercise-\the\value{exeNr}}}%
{\endfilecontentsdefmacro\endgroup}
\newcommand{\printexercise}[1]{\filecontentsexec{exercise-\the\numexpr#1\relax}}
\newcommand{\printsrcexercise}[1]{\filecontentsprint{exercise-\the\numexpr#1\relax}}
\begin{document}
\section{Talk about math}
Here we talk about addition and show that $1+1=2$.
\begin{savedexercise}
Compute $1+2$
\end{savedexercise}
Here we talk about integrals.
\begin{savedexercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$
\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{savedexercise}
\section{The exercises}
Now we can print the exercises.
\foreach \i in {1,...,2} {
\begin{exercise}
\printexercise{\i}
\end{exercise}
}
\section{The src exercises}
Now we can print the src of exercises.
\foreach \i in {1,...,2} {
\printsrcexercise{\i}
}
\section{Back to first exercises}
Remember the first exercise
\setcounter{exercise}{0}
\begin{exercise}
\printexercise{1}
\end{exercise}
\end{document}