% censor.sty \ProvidesPackage{censor} [2013/02/19 v3.00 Provides capability for redaction of sensitive information] %% Copyright 2009, 2012, 2013 Steven B. Segletes % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Steven B. Segletes. % Packege: CENSOR % CHOOSE MODE OF OPERATION: % 1) IF .tex FILE IS CREATED IN PRIVATE (SECURE) ENVIRONMENT: % a) To produce censored document, censor individual words with % \censor{word} % b) Censor text blocks with \blackout{...}, subject to limitations. % c) To produce uncensored document, place \StopCensoring in preamble % d) To produced a mixed document with some redaction, but elsewhere % turned off, place \StopCensoring and/or \RestartCensoring in % various document locations as needed. % % DISCLAIMER: Don't \censor whitespace (i.e., phrases), or justifications % could get fouled up. If space-laden phrase needs repeated censoring, % I suggest typesetting according to the following example: % \def\CodeName{\blackout{Little Bo Peep}} % In the text, refer to {\CodeName} as often as needed. % % 2) IF .tex FILE IS INITIALLY CREATED IN PUBLIC (UNSECURE) ENVIRONMENT: % a) To produce censored document, define (in the document preamble) % placeholders for all censored phrases, like: % \def\ProjectName{\censor*{7}} % In document, refer to {\ProjectName} as needed. The "7" refers % to the approximate width (in ex's) of the censored word. % b) Use of \StopCensoring in preamble will merely turn censored % black rectangles into underlined blank spaces, since uncensored % word is not known to the public source (.tex) document. % c) To produce uncensored document, the source code must be moved % to a private (secure) working environment. At that point, the % uncensored document may be created merely by editing the document % preamble and redefining the censored placeholders, so that % \def\ProjectName{\censor*{7}} becomes \def\ProjectName{Liberty}, % for example. Note that line justification could be affected, since % censored placeholders are not exactly the same width as the % actual word, in Mode 2 operation. % d) To produced (in the private/secure environment) a mixed document % with some redaction, but elsewhere turned off, place \StopCensoring % and/or \RestartCensoring in various document locations as needed. % % DISCLAIMER: Don't \censor whitespace (i.e., phrases), or justifications % could get fouled up. I suggest typesetting multi-word phrases according % to the following example: % \def\CodeName{\censor*{6} \censor*{2} \censor*{4}} % In the text, refer to {\CodeName} as often as needed. % % NOTE: For both modes of operation, placeholders are placed in curly % braces, so that surrounding white space and/or punctuation is properly % handled. % VERSION: % 1.00 - Initial release % 2.00 - Added \blackout % 2.10 - Allowed \blackout to cross paragraph boundaries with use of % \bpar. Stopped censoring periods, in order to preserve % end-of-sentence spacing, which differs from inter-word spacing. % 3.00 - \censorbox introduced to handle figures, tables, etc. \usepackage{pbox} \usepackage{ifnextok} \newcommand\censor{\@ifstar{\@cenlen}{\@cenword}} \newcommand\@cenlen[1]{\protect\rule[-.3ex]{#1 ex}{2.1ex}} \newcommand\@cenword[1]{% \protect\rule[-.3ex]{\widthofpbox{#1}}{2.1ex}} \newcommand\un@censor{\@ifstar{\un@cenlen}{\un@cenword}} \newcommand\un@cenlen[1]{\protect\underline{\hspace{#1 ex}}} \newcommand\un@cenword[1]{#1} \newcommand\StopCensoring{% \let\censor\un@censor% \let\censorbox\un@censorbox% } \newcommand\RestartCensoring{% \renewcommand\censor{\@ifstar{\@cenlen}{\@cenword}}% \renewcommand\censorbox{\@ifstar{\censor@dim}{\censor@box}}% } \def\stringend{$} \def\blackout#1{\censor@Block#1\stringend} \def\censor@Block{\IfNextToken\stringend{\@gobble}% {\IfNextToken\@sptoken{ \bl@t{\censor@Block}}% {\bl@t{\censor@Block}}}} % V2.00 DEFINITION: % \def\bl@t#1#2{\censor{#2}#1} % V2.10 DEFINITION: \def\bl@t#1#2{\if\bpar#2\par\else\if.#2#2\else\censor{#2}\fi\fi#1} \def\bpar{_} % ALTERNATE DEFINITION IF ABOVE PROVES PROBLEMATIC %\def\bl@t#1#2{\if.#2#2\else\censor{#2}\fi#1} % JUST PERIODS, NO \bpar \newcommand\censorbox{\@ifstar{\censor@dim}{\censor@box}} \newcommand\censor@dim[4][]{{#1% \rule[-#4\baselineskip]{#2ex}{#3\baselineskip}}} \newcommand\censor@box[2][]{#1\setbox0\hbox{#2}% \rule[-\the\dp0]{\the\wd0}{\the\ht0+\the\dp0}} \newcommand\un@censorbox{\@ifstar{\un@censor@dim}{\un@censor@box}} \newcommand\un@censor@dim[4][]{{#1% \fbox{\rule[-#4\baselineskip]{0ex}{#3\baselineskip} \rule{#2ex}{0ex}}}} \newcommand\un@censor@box[2][]{#1#2} % NOTE: A \protect\censorbox{} MAY BE REQUIRED INSIDE SOME ENVIRONMENTS \endinput