3

Below are two examples. The first one works fine, no errors no warnings, but on trying to build a doc from the latter, I get a heap of errors.

Working:

\documentclass[]{article}
\usepackage{environ}

\newsavebox{\DiscardedText}
\newcommand{\Slide}[1]{}
\newcommand{\SavedSlideText}{}
\newcommand\AddToSavedSlideText[1]{\xdef\SavedSlideText{\SavedSlideText#1\endgraf}}
\NewEnviron{GobbleExceptForSlide}{%
    \renewcommand{\Slide}[1]{\AddToSavedSlideText{##1}}%
    \savebox{\DiscardedText}{\BODY}%
    \SavedSlideText%
}

\AtBeginDocument{\GobbleExceptForSlide}
\AtEndDocument{\endGobbleExceptForSlide}

\begin{document}

Should not show in output

\Slide{Should show in output}

\end{document}

But if I put an itemize either below or into the Slide command, then it fails with Paragraph ended before \@savebox was complete \end{document}:

\Slide{

Should show in output

\begin{itemize}
 \item Item one
 \item Iten two
\end{itemize}

}

I'm tried replacing the 'newcommand' with 'newenvironment' and related changes, but I could not get that to work either. I'm a little rusty...

Update

The answer provided below does solve part of the problem, but for some reason it breaks when using an environment outside the Slide. The following tex won't compile, because there is an itemize environment outside of the Slide.

\documentclass{article}
\usepackage{environ}

\makeatletter
\newsavebox{\DiscardedText}
\newcommand{\Slide}[1]{}
\newcommand{\SavedSlideText}{}
\newcommand\AddToSavedSlideText[1]{\g@addto@macro\SavedSlideText{{#1}}}
\NewEnviron{GobbleExceptForSlide}{%
    \renewcommand{\Slide}[1]{\AddToSavedSlideText{##1}}%
    \savebox{\DiscardedText}{\BODY}%
    \SavedSlideText%
}
\makeatother

\AtBeginDocument{\GobbleExceptForSlide}
\AtEndDocument{\endGobbleExceptForSlide}

\begin{document}

Should not show in output

\begin{itemize}
 \item Item one
 \item Iten two
\end{itemize}

\Slide{
Should show in output

   \begin{itemize}
    \item Item one
    \item Iten two
   \end{itemize}
}

\end{document}
  • What does "\Slide" really do? I doubt it's an empty command like in your MWE. – 1010011010 Oct 27 '14 at 10:10
  • 1
    You can not use \edef or \xdef on general tex input, almost all commands are unsafe in that context. If you want to incrementally add tokens to a macro use \g@addto@macro\SavedSlideText{#1\endgraf}} – David Carlisle Oct 27 '14 at 10:27
  • @DavidCarlisle will you kindly see if you can make my content compile successfully and submit it as an answer. I've tried your suggestion, but I'm not able to get it to work. – Jack Oct 27 '14 at 11:28
  • @1010011010 The purpose of slide is to only show content inside the command and ignore all other parts of the document. The idea is to wrap parts of my document in slide environments so that I have an option to built only slides, or only the doc, but from the same content. – Jack Oct 27 '14 at 11:30
  • @JacobusR: Please reference the original question for a follow up to an existing question so that we know who to credit, or blame :-) in this case, for the problem. – Peter Grill Oct 27 '14 at 18:18
2

Update Based on revised MWE.

Unfortunately I don't know why this problem occurs. But, one way to proceed is to eliminate the warning of missing list items as per How to make itemize/enumerate/description environment robust to missing \item elements?

enter image description here

Code: Suppress Missing Item Error

\documentclass{article}
\usepackage{environ}

%% Allow for lists to have no items.
%% https://tex.stackexchange.com/questions/86547/how-to-make-itemize-enumerate-description-environment-robust-to-missing-item-el
\makeatletter
  \let\@oldnoitemerr\@noitemerr %Save the command definition                      
  \newcommand\IgnoreMissingItemError{\let\@noitemerr\relax}
  \newcommand\DontIgnoreMissingItemError{\let\@noitemerr\@oldnoitemerr}

\newsavebox{\DiscardedText}
\newcommand{\Slide}[1]{#1}
\newcommand{\SavedSlideText}{}
\newcommand\AddToSavedSlideText[1]{\g@addto@macro\SavedSlideText{{#1}}}
\NewEnviron{GobbleExceptForSlide}{%
    \renewcommand{\Slide}[1]{\AddToSavedSlideText{##1}}%
    \savebox{\DiscardedText}{\IgnoreMissingItemError\BODY}%
    \SavedSlideText%
}
\makeatother

\AtBeginDocument{\GobbleExceptForSlide}
\AtEndDocument{\endGobbleExceptForSlide}

\begin{document}

Should not show in output

\begin{itemize}
 \item Item one
 \item Iten two
\end{itemize}

\Slide{
Should show in output

   \begin{itemize}
    \item Item one
    \item Iten two
   \end{itemize}
}
\end{document}

An alternate approach is to typeset the document and save the \Slide content for output that content at the end of the document.

Code: Generate all content, and Slide content at end

\documentclass{article}
\usepackage{environ}

\makeatletter
\newcommand{\Slide}[1]{#1}
\newcommand{\SavedSlideText}{}
\newcommand\AddToSavedSlideText[1]{\g@addto@macro\SavedSlideText{{#1}}}
\NewEnviron{GobbleExceptForSlide}{%
    \renewcommand{\Slide}[1]{\AddToSavedSlideText{##1}##1}%
    \BODY%
}
\makeatother

\AtBeginDocument{\GobbleExceptForSlide}
\AtEndDocument{\endGobbleExceptForSlide\clearpage\SavedSlideText}

\begin{document}

\section{foo}

Should not show in output

\begin{itemize}
 \item Item one
 \item Iten two
\end{itemize}

\Slide{
Should show in output

   \begin{itemize}
    \item Item one
    \item Itenn two
   \end{itemize}
}
\end{document}

In your previous question Is there a way to display a specific command and hide the rest, there was no information as to the type of content that the \Slide macro would have. So, as David Carlisle suggested you need to use an alternate solution from How keep a running list of strings and then process them one at a time to save the content:

enter image description here

Code:

\documentclass{article}
\usepackage{environ}

\makeatletter
\newsavebox{\DiscardedText}
\newcommand{\Slide}[1]{}
\newcommand{\SavedSlideText}{}
\newcommand\AddToSavedSlideText[1]{\g@addto@macro\SavedSlideText{{#1}}}
\NewEnviron{GobbleExceptForSlide}{%
    \renewcommand{\Slide}[1]{\AddToSavedSlideText{##1}}%
    \savebox{\DiscardedText}{\BODY}%
    \SavedSlideText%
}
\makeatother

\AtBeginDocument{\GobbleExceptForSlide}
\AtEndDocument{\endGobbleExceptForSlide}

\begin{document}

Should not show in output

\Slide{
Should show in output

\begin{itemize}
 \item Item one
 \item Iten two
\end{itemize}

}
\end{document}
| improve this answer | |
  • Thank you very much Peter, and apologies for not referencing the original question. This one almost works, but when moving the itemize out of the Slide, it breaks again... darn. In my case I now have a copy of the itemize in the slide and out of the slide, and it stopped working. – Jack Oct 27 '14 at 20:02
  • @JacobusR: Please update the MWE in the question to show this problem. – Peter Grill Oct 27 '14 at 20:04
  • I have not been able to solve the problem and would be very grateful if you could have a second look at the updated question. – Jack Oct 29 '14 at 7:57
  • @JacobusR: Have provided a workaround. Please let me know if it works for you. – Peter Grill Oct 29 '14 at 18:41
  • Thank you very much Peter, this now solves the problem for itemize, but various other environments still cause problems. Don't worry about it further. I'm giving up for now! I'm marking your answer as correct, because it solves the described problem. Thank you very much for the help. – Jack Oct 30 '14 at 6:45

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.