I have a code listing to write in a report, but I'd like to blur or hide some code parts with a colored box (of same length as the hidden text), so that readers cannot see the hidden parts. (Another requirement is that readers should not be able to copy & paste the hidden text from the PDF.)
As an example, I would like b=c;
in the listing below to be hidden by a black box (or blurred).
For that, I define a \confidentiel
for hiding text in a black box.
It works fine on normal text ouside a listing block. However, it doesn't work inside an mcode
listing block: instead of producing a black box, \confidentiel{code to hide or blur}
gets printed verbatim.
I'm using the mcode
package to display Matlab code, but I suppose the listings
package (rather than mcode
) is to blame here, because mcode
uses the listings
package; the problem likely occurs no matter which listings
language is used.
Any idea?
\documentclass{article}
\usepackage{tikz} %to be used with package below:
\usepackage[confidentiel]{optional}
\newlength\heightconf
\newlength\widthconf
\newcommand\confidentiel[1]{%
\opt{confidentiel}{%
\settoheight{\heightconf}{#1}%
\settowidth{\widthconf}{#1}%
\tikz{\node[inner sep=0pt,rectangle,draw,anchor=base,text height=\heightconf,text width=\widthconf,fill=black]{};}%
}%
\opt{libre}{#1}}
% package to display matlab code:
\usepackage[framed,numbered,autolinebreaks,useliterate]{mcode}
%starting document
\begin{document}
\confidentiel{this text is hidden with black box}
this text is not hidden
\begin{lstlisting}
for i=1:3 do
a=b;
\confidentiel{b=c;}
c=d
end
\end{lstlisting}
% the code above does not hide b=c; but
% prints literaly \confidentiel{b=c} but i don't want that !
\end{document}
Best Answer
Here, all code is shown:
Here, some code is hidden:
Here are some implementation details.
Invoke the "ghosts" of Martin Scharrer and Donald Arseneau
The
\confidentiel
macro defined below is based on a modified version of Martin Scharrer's\UL@putbox
, which is itself a "phantom" version of a macro defined in Donald Arseneau'sulem
package.Such a macro applies cleanly over multiple lines, both inside and outside listings, and will prevent your readers from copying & pasting the hidden parts, no matter which PDF viewer they use.
Indulge yourself
Instead of escaping to LaTeX only to invoke your
\confidentiel
macro, the following approach defines delimiters that apply\confidentiel
to what they delimit.The backtick character,
`
, is an adequate (opening and closing) delimiter here, because it's unlikely to occur in Matlab code (it's only valid in Matlab string literals and system commands, nowhere else).The main benefits of this approach is that hiding/unveiling stuff, either locally or globally, is fast and easy.
`...`
), as opposed to adding/removing\confidentiel{...}
each time;\ifconfid
switch (comment/uncomment the line\confidtrue
).Use
matlab-prettifier
I recommend using the
matlab-prettifier
package instead ofmcode
... but, as the author of the former, I'm somewhat biased:p
Have a look at this answer, and see if you likematlab-prettifier
enough to migrate frommcode
.