我有一个代码清单要写在报告中,但我想用彩色框(与隐藏文本长度相同)模糊或隐藏某些代码部分,以便读者看不到隐藏部分。(另一个要求是读者不能从 PDF 中复制和粘贴隐藏文本。)
举个例子,我想b=c;
在下面的列表中用黑框隐藏(或模糊)。
为此,我定义了一个\confidentiel
用于将文本隐藏在黑框中的方法。它对列表块外的普通文本效果很好。但是,它在列表块内不起作用mcode
:它不会产生黑框,而是\confidentiel{code to hide or blur}
打印出来逐字。
我正在使用mcode
包裹显示 Matlab 代码,但我认为这里的罪魁祸首是listings
包(而不是),因为使用了包;无论使用哪种语言,都可能出现这个问题。mcode
mcode
listings
listings
任何想法?
\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}
答案1
这里显示所有代码:
这里隐藏了一些代码:
以下是一些实施细节。
召唤马丁·沙雷尔和唐纳德·阿瑟诺的“幽灵”
下面定义的宏基\confidentiel
于马丁·沙勒的\UL@putbox
,它本身是 Donald Arseneau 定义的宏的“幻影”版本ulem
包裹。
这样的宏可以干净地应用于列表内部和外部的多行,并且可以阻止读者复制和粘贴隐藏部分,无论他们使用哪种 PDF 查看器。
放纵自己
\confidentiel
以下方法不需要转为 LaTeX 来调用宏,而是定义适用\confidentiel
于其所界定内容的分隔符。
反引号字符 ,`
在这里是一个合适的(打开和关闭)分隔符,因为它不太可能出现在 Matlab 代码中(它仅在 Matlab 字符串文字和系统命令中有效,在其他地方无效)。
这种方法的主要好处是,隐藏/揭露内容,无论是本地或者全球,快捷又简单。
- 隐藏/揭露事物本地只需要添加/删除两个反引号(
`...`
),而不是\confidentiel{...}
每次都添加/删除; - 隐藏/揭露事物全球可以通过翻转开关
\ifconfid
(注释/取消注释该行\confidtrue
)来完成。
使用matlab-prettifier
我建议使用matlab-prettifier
包而不是mcode
...但是,作为前者的作者,我有点偏见:p
看看这个答案,看看你是否喜欢matlab-prettifier
足以从 迁移mcode
。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{matlab-prettifier}
\usepackage[normalem]{ulem}
\newif\ifconfid
\confidtrue % comment this line out to unveil all hidden text
\colorlet{confidcolor}{black} % change the colour of boxes here (e.g. "red")
% ----------- implementation details -----------
\makeatletter
% from Martin's Scharrer's answer (https://tex.stackexchange.com/a/16004/21891)
\def\confid@UL@putbox{%
\ifx\UL@start\@empty%
\else % not inner
\vrule\@width\z@ \LA@penalty\@M
{\UL@skip\wd\UL@box \UL@leaders \kern-\UL@skip}%
\phantom{\box\UL@box}%
\fi
}
\newcommand\confidentiel{}%
\ifconfid
\renewcommand\confidentiel[1][confidcolor]{%
\bgroup%
\let\UL@putbox\confid@UL@putbox%
\markoverwith{\hbox to.01em{\hss\textcolor{#1}{|}\hss}}\ULon%
}
\fi
\lst@AddToHook{Init}{%
\ifconfid%
\lstset{moredelim=[is][\confidentiel]``,keepspaces}%
\else
\lstset{moredelim=**[is][]``}%
\fi
}
\makeatother
% ----------- end of implementation details -----------
\lstset{
style=Matlab-editor,
basicstyle=\mlttfamily,
}
\begin{document}
\confidentiel{%
this text is hidden\\
this text is hidden\\
this text is hidden\\
}%
\xout{test that \textsf{ulem} works}
\begin{lstlisting}
for i=1:3
a=b;
% Guess what's next...
`b=c;`
c=d;
end
`% this text is hidden
% this text is hidden
% this text is hidden
`
\end{lstlisting}
\end{document}
答案2
正如所怀疑的,您只需添加escapechar
以便listings
知道您想要执行此代码:
笔记:
可以
escapechar
是任何未出现在 中的字符listing
,并指示要执行的代码的开始和结束。在下面的 MWE 中,我使用了$
字符。
代码:
\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}
\usepackage{listings}
%starting document
\begin{document}
\confidentiel{this text is hidden with black box}
this text IS hidden outside of \verb|listings|
\begin{lstlisting}[escapechar=$]
for i=1:3 do
a=b;
$\confidentiel{b=c;}$ And now, also hidden IN listings
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}