2

I have to create a series of exercises, all with the same items:

  • Title
  • Image
  • Questions
  • Solutions
  • etc..

I would like to create a separate file for each exercise and then from my main document be able to reference these specific sections multiple times. I want to be able to put equations, images, tikz, etc... within each item.

I considered creating a file with macro definitions for each case, e.g.:

ex1.sty

\newcommand\ex1sol{
(contents)
}
...

Then call the macros where needed but this is not working, and I feel there has to be a better solution anyway, since this does not seem like a rare application. Essentially it means to present the same content in different formats.

Ingmar
  • 6,690
  • 5
  • 26
  • 47
jsb
  • 454

1 Answers1

1

As a variant of my answer to Using Latex code chunks as library - For reusing latex elements such as figures in multiple representations I can offer an interface where files with specifiable sections are of pattern

\filesection{⟨name of section⟩}
⟨code⟩
\endfilesection
%-------------------------------------------------------------
\filesection{⟨name of section⟩}
⟨code⟩
\endfilesection
%-------------------------------------------------------------
\filesection{⟨name of section⟩}
⟨code⟩
\endfilesection
%-------------------------------------------------------------
\endinput

You input these files with the command

\inputfilesection{⟨name of file⟩}{⟨name of section⟩}

The ⟨code⟩ of a file-section will be executed only if both the \inputfilesection-command and the \filesection-comand have the same ⟨name of section⟩-argument.

In this case ⟨code⟩ will be read under verbatim-catcode-régime. Then the result is passed to \scantokens for re-tokenization and normal processing.

Several \filesections can have the same ⟨name of section⟩. In this case all file-sections of the name in question occurring in the file are delivered by \inputfilesection.

CAVEATS I AM AWARE OF:

!!!Don't do \inputfilesection inside files that are called by \inputfilesection!!!

%
% An example file with \filesection-commands:
%
%\begin{filecontents*}[overwrite]{FileWithSections.tex}
\begin{filecontents*}{FileWithSections.tex}
\filesection{First Section}
Some text in First Section Of FileWithSections.tex.
\begin{verbatim*}
Some verbatim material in 
First Section Of FileWithSections.tex.
\end{verbatim*}
\endfilesection
%-------------------------------------------------------------
\filesection{Second Section}
Some text in Second Section Of FileWithSections.tex.
\begin{verbatim*}
Some verbatim material in 
Second Section Of FileWithSections.tex.
\end{verbatim*}
\endfilesection
%-------------------------------------------------------------
\filesection{Third Section}
Some text in Third Section Of FileWithSections.tex.
\begin{verbatim*}
Some verbatim material in 
Third Section Of FileWithSections.tex.
\end{verbatim*}
\endfilesection
%-------------------------------------------------------------
\endinput
\end{filecontents*}

\documentclass{article} \usepackage{graphicx}

\makeatletter %///// start of code that could go into a package / .sty-file////////////////// @ifundefined{NewDocumentCommand}{\RequirePackage{xparse}}{}% \NewDocumentCommand\inputfilesection{mm}{% \def@stringincommand{#2}% \input{#1}% }% \newcommand@stringincommand{}% \newcommand@stringinfile{}% \NewDocumentCommand\filesection{m}{% \begingroup \let\do@makeother\dospecials \do^^I% \do^^M% @filesection{#1}% }% \begingroup \newcommand@filesection[2]{% \endgroup \def@filesection##1##2#1{% \def@stringinfile{##1}% \expandafter\endgroup \ifx@stringinfile@stringincommand\expandafter@firstofone\else\expandafter@gobble\fi {% \begingroup \newlinechar=\endlinechar \scantokens\expandafter\expandafter\expandafter{% \expandafter\expandafter\expandafter\endgroup \UD@RemoveLeadingNTrailingCarriageReturn{##2}#2}% }\ignorespaces }% }% @firstofone{% \let\do@makeother\dospecials \catcode\{=1 % \catcode}=2 % @filesection }{\endfilesection}{\ignorespaces%}% %================================================================================= % Begin of code for removing one leading and one trailing explicit % <carriage-return>-character-token of catcode 12(other) from verbatimized % argument %================================================================================= @ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`^^00}% %%----------------------------------------------------------------------------- %% Check whether argument is empty: %%............................................................................. %% \UD@CheckWhetherNull{<Argument which is to be checked>}% %% {<Tokens to be delivered in case that argument %% which is to be checked is empty>}% %% {<Tokens to be delivered in case that argument %% which is to be checked is not empty>}% %% %% The gist of this macro comes from Robert R. Schneck's \ifempty-macro: %% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J> \newcommand\UD@CheckWhetherNull[1]{% \romannumeral\expandafter@secondoftwo\string{\expandafter @secondoftwo\expandafter{\expandafter{\string#1}\expandafter @secondoftwo\string}\expandafter@firstoftwo\expandafter{\expandafter @secondoftwo\string}\expandafter\UD@stopromannumeral@secondoftwo}{% \expandafter\UD@stopromannumeral@firstoftwo}% }% %%----------------------------------------------------------------------------- \begingroup @makeother^^M% @firstofone{% \endgroup% %%============================================================================= %% Check whether_verbatimized_ argument has a leading explicit %% <carriage-return>-character-token of catcode 12(other): %%----------------------------------------------------------------------------- %% \UD@CheckWhetherLeadingCarriageReturn{<Argument which is to be checked>}% %% {<Tokens to be delivered in case %% <argument which is to be checked>'s %% 1st token is an explicit <carriage- %% return>-character-token of %% catcode 12(other)>}% %% {<Tokens to be delivered in case %% <argument which is to be checked>'s %% 1st token is not an explicit %% <carriage-return>-character-token of %% catcode 12(other)>}% \newcommand\UD@CheckWhetherLeadingCarriageReturn[1]{% \UD@@CheckWhetherLeadingCarriageReturn\UD@SelDom#1\UD@SelDom^^M\UD@@SelDom% }% @ifdefinable\UD@@CheckWhetherLeadingCarriageReturn{% \long\def\UD@@CheckWhetherLeadingCarriageReturn#1\UD@SelDom^^M#2\UD@@SelDom{% \UD@CheckWhetherNull{#2}{@secondoftwo}{@firstoftwo}% }% }% %%----------------------------------------------------------------------------- %% Check whether_verbatimized_ argument having a leading explicit <carriage- %% return>-character-token of catcode 12(other) consists only of such tokens: %%----------------------------------------------------------------------------- %% \UD@CheckWhetherOnlyCarriageReturn{<Argument which is to be checked and %% which is known to have a leading explicit %% <carriage-return>-character-token of %% catcode 12(other)>}% %% {<Tokens to be delivered in case <argument %% which is to be checked> consists only %% of explicit <carriage-return>-character- %% tokens of catcode 12(other)>}% %% {<Tokens to be delivered in case <argument %% which is to be checked> does not consist %% only of explicit <carriage-return>- %% character-tokens of catcode 12(other)>}% \newcommand\UD@CheckWhetherOnlyCarriageReturn[1]{% \UD@CheckWhetherLeadingCarriageReturn{#1}{% \expandafter\UD@CheckWhetherOnlyCarriageReturn% \expandafter{\UD@@TrimLeadingCarriageReturn#1}% }{% \UD@CheckWhetherNull{#1}{@firstoftwo}{@secondoftwo}% }% }% %%----------------------------------------------------------------------------- %% Remove one leading explicit <carriage-return>-character-token of %% catcode 12(other) from verbatimized argument: %%----------------------------------------------------------------------------- @ifdefinable\UD@@TrimLeadingCarriageReturn{% \long\def\UD@@TrimLeadingCarriageReturn^^M{}% }% %%----------------------------------------------------------------------------- %% Check whether_verbatimized_ argument has a trailing explicit %% <carriage-return>-character-token of catcode 12(other): %%----------------------------------------------------------------------------- %% \UD@CheckWhetherTrailingCarriageReturn{<Argument which is to be checked>}% %% {<Tokens to be delivered in case %% <argument which is to be checked>'s %% last token is an explicit <carriage- %% return>-character-token of %% catcode 12(other)>}% %% {<Tokens to be delivered in case %% <argument which is to be checked>'s %% last token is not an explicit %% <carriage-return>-character-token of %% catcode 12(other)>}% \newcommand\UD@CheckWhetherTrailingCarriageReturn[1]{% \UD@@CheckWhetherTrailingCarriageReturn#1\UD@SelDom^^M\UD@SelDom\UD@@SelDom% }% @ifdefinable\UD@@CheckWhetherTrailingCarriageReturn{% \long\def\UD@@CheckWhetherTrailingCarriageReturn#1^^M\UD@SelDom#2\UD@@SelDom{% \UD@CheckWhetherNull{#2}{@secondoftwo}{@firstoftwo}% }% }% %%----------------------------------------------------------------------------- %% Remove one trailing explicit <carriage-return>-character-token of %% catcode 12(other) from verbatimized argument: %%----------------------------------------------------------------------------- \newcommand\UD@TrimTrailingCarriageReturn[1]{% \UD@@TrimTrailingCarriageReturn#1\UD@SelDom% }% @ifdefinable\UD@@TrimTrailingCarriageReturn{% \long\def\UD@@TrimTrailingCarriageReturn#1^^M\UD@SelDom{#1}% }% %%----------------------------------------------------------------------------- %% Remove one leading and one trailing explicit <carriage-return>-character- %% token of catcode 12(other) from verbatimized argument if present. %% In the edge case of the verbatimized argument consisting only of explicit %% <carriage-return>-character-tokens of catcode 12(other) remove only one of %% them. %% Due to \romannumeral-expansion the result is delivered in 2 expansion-steps: %%----------------------------------------------------------------------------- \newcommand\UD@RemoveLeadingNTrailingCarriageReturn[1]{% \romannumeral% \UD@CheckWhetherLeadingCarriageReturn{#1}{% \UD@CheckWhetherTrailingCarriageReturn{#1}{% \UD@CheckWhetherOnlyCarriageReturn{#1}{% \expandafter\UD@stopromannumeral\UD@@TrimLeadingCarriageReturn#1% }{% \expandafter\expandafter\expandafter\expandafter\expandafter% \expandafter\expandafter\UD@stopromannumeral\expandafter% \UD@TrimTrailingCarriageReturn\expandafter{\UD@@TrimLeadingCarriageReturn#1}% }% }{% \expandafter\UD@stopromannumeral\UD@@TrimLeadingCarriageReturn#1% }% }{% \UD@CheckWhetherTrailingCarriageReturn{#1}{% \expandafter\expandafter\expandafter\UD@stopromannumeral% \UD@TrimTrailingCarriageReturn{#1}% }{\UD@stopromannumeral#1}% }% }% }% %================================================================================ % End of code for removing one leading and one trailing explicit % <carriage-return>-character-token of catcode 12(other) from verbatimized % argument %================================================================================ %///// end of code that could go into a package / .sty-file//////////////////// \makeatother

\begin{document}

\noindent \inputfilesection{FileWithSections.tex}{First Section}

\noindent\hrule\null

\noindent \inputfilesection{FileWithSections.tex}{Second Section}

\noindent\hrule\null

\noindent \inputfilesection{FileWithSections.tex}{Third Section}

\noindent\hrule\null

\noindent \inputfilesection{FileWithSections.tex}{First Section}

\noindent\hrule\null

\noindent \inputfilesection{FileWithSections.tex}{Second Section}

\noindent\hrule\null

\noindent \inputfilesection{FileWithSections.tex}{Third Section}

\end{document}

enter image description here

Ulrich Diez
  • 28,770