나중에 사용할 수 있도록 텍스트 비트를 강력하게 저장하는 방법

나중에 사용할 수 있도록 텍스트 비트를 강력하게 저장하는 방법

학생들을 위한 문제 세트를 준비할 수 있도록 연습 패키지와 비슷한 패키지를 직접 작성하려고 합니다. 문서의 적절한 위치에 도달할 때까지 문제 및/또는 솔루션 출력을 연기하고 싶습니다. 나는 일종의 작동하는 것을 가지고 있지만 그것은 다소 투박합니다. 예를 들어, 이것은 꽤 잘 작동합니다:

\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단지 예를 들어 사용했습니다.

여기에 이미지 설명을 입력하세요

xparse2019-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

다음은 변형입니다.에그레그의 답변이는 \romannumeraland \exchange대신 \xdefand 를 사용합니다 \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}

얻은 출력의 예

관련 정보