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.

0

1 Answer 1

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.