15

I am quite new to LaTeX so my question may be trivial, but I haven't found a good solution so far.

I am preparing some lecture notes and I would like to have 2 different versions: one for myself, containing all the info I need during the lecture, and one for the students, with some of the text and/or graphics and/or equations blanked out (with some white space occupying the same space on the page, so the students could fill the gaps). I know of \phantom, but it does not seem very efficient as I would have to prepare 2 versions of the same document. I have also seen the censor package, but it does not seem to play nicely with equations. Any other suggestion on how to do this cleanly and efficiently?

4
10

I have often done the same thing; in the education community here in the U.S., it's called a skeleton outline.

I prepare the note for myself, including all diagrams, solutions, comments, etc. I also include extra vertical spacing because my students are not able to write as small or as neatly as LaTeX. (It would sure make my job simpler if they could!)

Finally, to prepare the student version, I go back to the sections I want to hide from my students and wrap them with

\color{white}{ here's the hidden text }

It's low tech, but as long as I make any edits in the original, complete file, creating the student version only takes a minute or two.

2
  • 8
    But this still allows one to copy the text from the pdf, doesn't it?
    – lhf
    Sep 28 '13 at 13:39
  • 1
    @lhf you could define a new command in the comments such as \newcommand{\col}{\color{white}}, enclose all the hidden text with {\col hidden text }. Then for the non-student version use \newcommand{\col}{} in the preamble.
    – Jim Conant
    Feb 24 '17 at 5:59
5

Use this answer as a starting point...

Put the code that has to be hidden inside the environment \begin{master}...\end{master}.

When you want the students' version uncomment the line

%\studenttrue

Complete MWE

\documentclass{report}
\usepackage{xcolor,lipsum}

\newif\ifstudent

%\studenttrue

\makeatletter
\newenvironment{master}{%
  \ifstudent\def\@eqnnum{{\normalfont \color{white} (\theequation)}}\color{white}%
  \else\def\@eqnnum{{\normalfont \normalcolor (\theequation)}}\normalcolor%
  \fi}{}
\makeatother

\begin{document}
\lipsum[1]

\begin{master}
  \lipsum[1]
  \begin{equation}
    \omega
  \end{equation}
  \lipsum[1]
\end{master}

\lipsum[1]
\begin{equation}
  \omega
\end{equation}
\lipsum[1]
\end{document} 

Of course the answer is full of limitations...

5

In this answer, List of Underlining Packages - Pros and Cons, I modified censor to underline with the text still intact, allowing for line breaks, even breaking the underline for descending letters (but it doesn't handle hyphenation). Most importantly, I added a math underlining/censoring capability.

So I took that solution, and removed the stuff that places the text there, leaving just the underlining. Then by setting \censorruleheight=0ex, the underline is set to zero thickness and so it disappears. So you have \censor for a string of words on a single line, \blackout for a group of words across multiple lines, and \mblackout for math expressions.

This approach does allow for blankspace that spans not only multiple lines, but even page breaks!

\documentclass{article}
\usepackage{censor}
\usepackage{stackengine}
\usepackage{scalerel}
\censorruleheight=0ex
\makeatletter
\long\def\blackout#1{%
  \def~{-}%
  \protected@edef\save@arg{#1}%
  \expandafter\censor@Block\save@arg\stringend\let~\sv@tilde}
\let\sv@cenword\@cenword
\newcommand\m@cenword[1]{\ThisStyle{%
  \stackengine{\mcensorruledepth}{$\SavedStyle\phantom{#1}$}%
    {\rule{\widthof{$\SavedStyle#1$}}{\the\censorruleheight}}{U}{c}{F}{T}{L}}}
\newcommand\mblackout[2][\dp\strutbox]{%
  \let\@cenword\m@cenword%
  \def\mcensorruledepth{#1}%
  \blackout{{#2}}%
  \let\@cenword\sv@cenword%
}
\makeatother
\parskip 1em
\begin{document}
The \verb|\censor| command can blackout \censor{this text} which appears on a single line.

The  \verb|\blackout| command allows the censoring of text even if it crosses a line/page boundary.
To test this macro, let's see \blackout{if this block of text is truly blacked out} across a line boundary.

For total blanking, there should be no need for \verb|\xblackout|.

But here is math versions, not black out, then blacked out:
\[ y = A x^2 + Bx + C + D\]
\[ y = \mblackout{A x^2} + Bx + \mblackout{C} + D\]

\[ y = \frac{a^3 + b^2 + c}{d_3}  + \frac{a^3 + b^2 + c}{d_3}\]
\[ y = \mblackout{\frac{a^3 + b^2 + c}{d_3}}  + \frac{a^3 + b^2 + c}{d_3}\]
\end{document}

enter image description here

2
  • This is an old comment but even in 2018 there doesn't seem to be many optimal solutions: is there a way to blank inline mathematics as part of the solution offered here?
    – TSGM
    Jul 16 '18 at 5:22
  • @TSGM I believe the provided \mblackout should work for inline math. Jul 16 '18 at 11:31
4

\hide replaces its argument with whitespace. A pagebreak inside the white space is not possible!

\documentclass{article}
\usepackage{varwidth,lipsum}
\newcommand\hide[1]{\phantom{\varwidth{\linewidth}#1\endvarwidth}}
\begin{document}
\lipsum[5]
\hide{\lipsum[5]}    
\lipsum[5]
%
\[ f(x)=\int_1^\infty \frac1{x^2} \mathrm{d}x \]
%
foo
%
\hide{\[ f(x)=\int_1^\infty \frac1{x^2} \mathrm{d}x \]}
%
bar
%
\[ f(x)=\int_1^\infty \hide{$\frac1{x^2}$} \mathrm{d}x \]
\end{document}

enter image description here

4

This is the solution I adopted:

\ExplSyntaxOn
        \box_new:N \l_mypkg_box
        \int_new:N \l_mypkg_cleanup_int
        \DeclareDocumentCommand{\hideit}{O{1}+m}
              {
                \tex_setbox:D \l_mypkg_box \tex_vbox:D
                  {
                    #2\par
                    \dim_zero:N \tex_baselineskip:D
                    \dim_zero:N \tex_lineskip:D
                    \dim_zero:N \tex_lineskiplimit:D
                    \int_set:Nn \l_mypkg_cleanup_int {#1}
                    \mypkg_dismantle_loop:
                  }
                \tex_unvbox:D \l_mypkg_box
              }
            \cs_new_protected:Npn \mypkg_dismantle_loop:
              {
                \prg_replicate:nn { \l_mypkg_cleanup_int }
                  {
                    \skip_if_eq:nnT { \tex_lastskip:D } { \c_zero_skip } { \tex_unskip:D }
                    \dim_compare:nT { \tex_lastkern:D = \c_zero_dim } { \tex_unkern:D }
                    \int_compare:nT { \tex_lastpenalty:D = \c_zero } { \tex_unpenalty:D }
                  }
                \skip_if_eq:nnTF { \tex_lastskip:D } { \c_zero_skip }
                  {
                    \dim_compare:nTF { \tex_lastkern:D = \c_zero_dim }
                      {
                        \int_compare:nTF { \tex_lastpenalty:D = \c_zero }
                          {
                            \box_set_to_last:N \l_mypkg_box
                            \box_if_empty:NF \l_mypkg_box
                              { \mypkg_dismantle_box: }
                          }
                          { \mypkg_dismantle_penalty: }
                      }
                      { \mypkg_dismantle_kern: }
                  }
                  { \mypkg_dismantle_skip: }
              }
            \cs_new_protected:Npn \mypkg_dismantle_skip:
              { \mypkg_dismantle_aux:nN { \tex_vskip:D \skip_use:N \tex_lastskip:D } \tex_unskip:D }
            \cs_new_protected:Npn \mypkg_dismantle_kern:
              { \mypkg_dismantle_aux:nN { \tex_kern:D \dim_use:N \tex_lastkern:D } \tex_unkern:D }
            \cs_new_protected:Npn \mypkg_dismantle_penalty:
              { \mypkg_dismantle_aux:nN { \tex_penalty:D \int_use:N \tex_lastpenalty:D } \tex_unpenalty:D }
            \cs_new_protected:Npn \mypkg_dismantle_box:
              { \mypkg_dismantle_aux:nN { \tex_vbox:D to \dim_eval:n { \box_ht:N \l_mypkg_box + \box_dp:N \l_mypkg_box } { } } \scan_stop: }
            \cs_new_protected:Npn \mypkg_dismantle_aux:nN #1#2
              {
                \use:x
                  {
                    #2
                    \mypkg_dismantle_loop:
                    #1 \scan_stop:
                  }
}
\ExplSyntaxOff

%conditional compilation for students version of document
\newif\ifstudents
%\studentstrue % comment out to hide text and equations


\begin{document}
Some text.
   \ifstudents \hideit[2]{ \fi
   \begin{equation*}
        \Delta H_{\mathrm{r},T_{2}} = \Delta H_{\mathrm{r},T_{1}} +\int\limits_{T_{1}}^{T_{2}} \Delta C_{p}\diff T 
   \end{equation*}
   \ifstudents } \fi
\end{document}

which is illustrated here too

2
  • 1
    +1 for showing your solution. Happy that my answer helped you in this! Oct 6 '13 at 8:09
  • You could make a package out of this! May 30 '18 at 0:29
1

Sorry to bring up an old thread, but I made this; a different, smaller approach (using mostly plain TeX):

The following does not make space across multiple pages (although, I made a similar answer here that does). Also it works with verbatim commands like listings

\documentclass{article}
\usepackage{comment}
\usepackage{lipsum}
\usepackage{tikz}
% Make ourselves a new conditional
% Use \HideSolutionstrue to "activate" it
\newif\ifHideSolutions
% Make a solution environment
\generalcomment{solution}{%
  \begingroup
  \ifHideSolutions%
  % if \HideSolutionstrue is not called, then we remove the contents
  \def\ProcessCutFile{}\fi%
}{%
  \ifHideSolutions%
    % aand,now (also when it's not called), we make a box
    % and then we \input the \CommentCutFile.
    \setbox1=\vbox{\input{\CommentCutFile}}%
    % Get the height from \ht1 and use \vskip to make appropriate space
    \vskip\ht1
  \fi
\endgroup%
}

%Uncomment below to hide solutions
\HideSolutionstrue

\begin{document}
  Some problem text goes here

  \begin{solution}
    \textbf{SOLUTION 1}
    \[ \forall\varepsilon>0\exists\delta>0:\dots \]
    \tikz{\draw(0,0)--(3,2);}
\end{solution}
%^ \end{solution} has to be ALONE on line without any prior spaces

  BETWEEN

\begin{solution}
    \textbf{SOLUTION 2}
    \[ \forall\varepsilon>0\exists\delta>0:\dots \]
\end{solution}
%^ has to be ALONE on line without any prior spaces
  Some text after solution.

\end{document}
0

Being in the same boat, I've searched for an answer that I could work with and found some useful pieces although I can't recall exactly from where. Then, I came up with my own, though possibly not so elegant, solution. One thing I couldn't solve "was" (see my comment below the post) the overflowing white censor box to the right of the margin in the environment mycensorboxx created using minipage with \linewidth (see the attached figures with frame to show the overflow). This does not create any problems for my simple purposes. Note that I am relying mainly on the censor package. I am adding the code here. I hope it helps.

\documentclass[letterpaper, 11pt]{report}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{amsmath}

% ==========================
% Create a \begin{mycensorboxx} \end{mycensorboxx} environment for lists, tabular, align, \[\], etc. (Does not work with table) - This is as far as I could manage. A better more versatile code could be written.
\newenvironment{mycensorboxx}
{\iftoggle{censorfigure}{}{\color{blue}}
\setbox0=\vbox\bgroup}%
{\egroup\iftoggle{censorfigure}{\censorbox[\color{white}]{\box0}}{\censorbox[\color{blue}]{\box0}}}

% Then create a command with the environment in its argument to wrap it up
\newcommand*\mycensorbox[1]{%
\begin{minipage}[htbp]{\linewidth-5.1\fboxsep-5.1\fboxrule}}
\begin{mycensorboxx} 
{#1}
\end{mycensorboxx}
\end{minipage}
}

% Create a tabular environment with some spacing above and below
\newenvironment{mytabular}{\vspace*{0.7\baselineskip}\tabular{\endtabular\vspace*{0.7\baselineskip}}

% Load censor package
\usepackage{censor}

% Colors text (to be hidden from students) blue when in teacher mode
\newcommand{\mycensor}[1]{\censor{\color{blue}#1\color{black}}}
\def\censordot{ }

% Modify blackout and mblackout for blue color in teacher mode
\usepackage{stackengine}
\usepackage{scalerel}
\censorruleheight=0ex
\makeatletter
\long\def\blackout#1{%
\def~{-}%
\color{blue}\protected@edef\save@arg{#1}%
\expandafter\censor@Block\save@arg\stringend\let~\sv@tilde~\color{black}}
\let\sv@cenword\@cenword
\newcommand\m@cenword[1]{\ThisStyle{%
\stackengine{\mcensorruledepth}{$\SavedStyle\phantom{#1}$}%
{\rule{\widthof{$\SavedStyle#1$}}{\the\censorruleheight}}{U}{c}{F}{T}{L}}}
\newcommand\mblackout[2][\dp\strutbox]{%
\let\@cenword\m@cenword%
\def\mcensorruledepth{#1}%
\blackout{{#2}}%
\let\@cenword\sv@cenword%
}
\makeatother

% Create a toggle to switch back and forth between teacher/student modes. Also used for double versioning of, e.g., figures, etc.
\newtoggle{censorfigure}
\toggletrue{censorfigure}

% For space around dx in integrals, use: \dif x (optional, smt I prefer in integrals
\newcommand*\dif{\mathop{}\!\mathrm{d}}
% ==========================

% This is where teacher/student version switching occurs:
% Uncomment the following 3 lines for full, comment for student version
\togglefalse{censorfigure}
\StopCensoring
\renewcommand\censordot{.} % To ensure \blackout works well with period

% =======================================================
\begin{document}
% First figure in student mode (blank version), second figure in teacher mode.

\begin{figure}[htp]
\centering\iftoggle{censorfigure}
{\includegraphics[scale=0.7]{BlankFigure}} % student version
{\includegraphics[scale=0.7]{FullFigure}}  % teacher version
\caption{Bla bla.}
\end{figure}

Here is the regular tabular environment:

\mycensorbox{
\begin{tabular}{ll}
$x$:    & Bla bla \\
$y$:    & Bla bla
\end{tabular}}

And here is the other tabular environment with space around:

\mycensorbox{
\begin{mytabular}{ll}
$x$:    & Bla bla \\
$y$:    & Bla bla \\
\end{mytabular}}

Math:

\mycensorbox{
\begin{align*}
f(x) = \; & \left\{
\begin{array}{@{ }cl}
\dfrac{1}{b-a}  & a < x < b \\
0       & \text{otherwise}
\end{array}
\right.
\end{align*}}

\mycensorbox{\[F(x) = \int_{-\infty}^{x} f(u) \dif u\]}

\mycensorbox{\begin{itemize}
\item Here is a bullet.
\item Another bullet.
\end{itemize}
}

Be careful with backslash. I sometimes use \texttt{mblackout} but I mostly prefer the regular \texttt{blackout}. Check how the period also works.

\blackout{{$x^{2} + 5 = z$}.}

Want: \blackout{Some text to be hidden} and some visible.

\blackout{{\texttt{Blackout} works with paragraphs too.  Bla bla bla \texttt{Blackout} works with paragraphs too. Bla bla bla \texttt{Blackout} works with paragraphs too. Bla bla bla \texttt{Blackout} works with paragraphs too. Bla bla bla \texttt{Blackout} works with paragraphs too. Bla bla bla \texttt{Blackout} works with paragraphs too. Bla bla bla \texttt{Blackout} works with paragraphs too. Bla bla bla}.}

\end{document}

Teacher version (full with blue colored text and new pic Student version (censored) with only \linewidth in minipage enclosing the mycensorbox environment in the preamble Student version (censored)-After revision

1
  • {\linewidth-5.1\fboxsep-5.1\fboxrule} instead of the {\linewidth} in the minipage environment enclosing the created mycensorbox environment seems to solve the overflowing problem. I updated the solution.
    – angie
    May 16 '20 at 21:14

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.