summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/luacensor/luacensor.sty
blob: 22a8003e2d3a9c92f304d51c5ecb1b5b121c0cb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
%luacensor.sty
\def\luacensorversionnumber{1.1.0}
\ProvidesPackage{luacensor}
[2022/02/22 \luacensorversionnumber\
 Redact sensitive information using Lua]
% !TeX program = lualatex                                   
% !TeX encoding = utf8
% 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 Elijah Z Granet
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% option (we'll come back
% to this later
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newif\ifwarning
\warningfalse
\DeclareOption{warning}{\warningtrue}
\ProcessOptions*
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DEPENDENCIES
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{luacode}
\RequirePackage{environ}% http://ctan.org/pkg/environ

\RequirePackage{verbatim}
% ^ for the censoring
\RequirePackage{accsupp}
%^for accessibility
\RequirePackage{fontspec}
%^for black lines
%in theory, you could do 
%a lighter version of this
%package with just asterisks 
%or `[TEXT-REDACTED]'
%And perhaps that would be better for
%the environment with printing
%BUT I MADE MY CHOICE!
\RequirePackage{xcolor}
\RequirePackage{graphicx}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FONTS
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% redacted is prettier and free to download
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Strongly recommended
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\IfFontExistsTF{Redacted}{%
\newfontface\cnsrfnt[%%%%%%
%the scale is arbitrary, but kind of works
%Scale=1.1,
%%the below declarations are to prevent warnings about shapes not being available
%WordSpace=0,
ItalicFont={Redacted},%
BoldItalicFont={Redacted},%
BoldFont={Redacted},%
SmallCapsFont={Redacted}]{Redacted}
\newcommand{\onething}{\cnsrfnt\ • }
\newcommand{\twothings}{\cnsrfnt\ • •}
\newcommand{\donothing}{\cnsrfnt\ }
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%The little spaces let justification happen
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% • chosen as an arbitrary average width
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
}{
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This option works perfectly
%fine, it's just less pretty
%%but a good fallback because
% Source Sans is in TeX dists by default
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newfontface\cnsrfnt[Scale=1.01,%To allow for separate use of source sans in text
WordSpace=0,%To make it all one black line
%the below declarations are to prevent warnings about shapes not being available
ItalicFont={Source Sans Pro Black},BoldItalicFont={Source Sans Pro Black},BoldFont={Source Sans Pro Black},SmallCapsFont={Source Sans Pro Black}]{Source Sans Pro Black}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bit of unicode magic below to make the black line effect
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\onething}{\cnsrfnt ▬ }
\newcommand{\twothings}{\cnsrfnt ▬ ▬ }
\newcommand{\donothing}{ }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A neat fallback for disappearing things…
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FULL CREDIT
% and FULSOME THANKS
% TO TEX.SE USER
% Werner  for the code below
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\newcommand{\voidenvironment}[1]{%
  \expandafter\providecommand\csname env@#1@save@env\endcsname{}%
  \expandafter\providecommand\csname env@#1@process\endcsname{}%
  \@ifundefined{#1}{}{\RenewEnviron{#1}{}}%
}
\makeatother
\newcommand{\hddn}[1]{%
\ifcnsr{}\else%
#1\fi}
\newenvironment*{hidden}{\begin{@empty}
}{\end{@empty}}
\voidenvironment{hidden}

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the CENSOR COMMAND
%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newif\ifcnsr\cnsrfalse
\newcommand{\cnsr}[1]{%
\ifcnsr{%
\voidenvironment{equation*}%
\voidenvironment{equation}%
\voidenvironment{table}%
\voidenvironment{table*}%
\voidenvironment{tabular}%
\voidenvironment{tabular*}%
\voidenvironment{}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% I don't know how many
% people use TEX native accent commands
% in LuaTEX given that using Unicode is more
%people's style.  But just in case, because these can lead to stray accent marks floating above censored letters.
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand{\`}[1]{}%
\renewcommand{\'}[1]{}%
\renewcommand{\^}[1]{}%
\renewcommand{\"}[1]{}%
\renewcommand{\H}[1]{}%
\renewcommand{\~}[1]{}%
\renewcommand{\c}[1]{}%
\renewcommand{\k}[1]{}%
\renewcommand{\l}[1]{}%
\renewcommand{\=}[1]{}%
\renewcommand{\b}[1]{}%
\renewcommand{\.}[1]{}%
\renewcommand{\d}[1]{}%
\renewcommand{\r}[1]{}%
\renewcommand{\u}[1]{}%
\renewcommand{\v}[1]{}%
\renewcommand{\t}[1]{}%
\renewcommand{\o}[1]{}%
\renewcommand{\i}[1]{}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%d
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% here we have the accsupp magic
% this operates by replacing the 'x's 
% or unicode black squares as the case
% may be with an alt text
% this serves a dual purpose of both making 
%pdftotext not break with huge strings of meaningless characters
%but more importantly
% it means screen readers don't subject
%. their users to the meaningless reading out of unicode black squares 50 times in a row!
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\BeginAccSupp{method=plain,ActualText={TEXT REDACTED}}%
\rndstring{#1}%
\EndAccSupp{}}%
\else%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% if the conditional is off
% the command does absolutely nothing
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
#1%
\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The LUA MAGIC PART
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{luacode}
--fulsome thanks to TeX.SE users Henri Menke and David Carlisle, without whom none of this would be possible 
local function rndstring()
    local toks = token.scan_toks(s)
        local on = true
for n, t in ipairs(toks) do
    if t.csname == "begin" or t.csname == "end" then
       on = false
-- The below is necessary as TeX primitives can break the code otherwise because they do not use brackets       
    end
   
   if not(on) and t.cmdname == "right_brace" then
     on = true
     -- This prevents needless errors about gibberish up commands
end
if on and t.csname ==  "&" then
  local letter = token.create'donothing'
 toks[n] = letter
 
elseif on and t.csname == "%" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "$" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "#" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "_" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "{" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "}" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "~" then
  local letter = token.create'donothing'
 toks[n] = letter

elseif on and t.csname == "^" then
  local letter = token.create'donothing'
 toks[n] = letter
elseif on and t.cmdname ==  "letter" then
-- The below is the randomness part of this, which I admit is fairly arbitrary, but will more often  artificially shorten strings than lengthen them, as testing found if lengthening was too frequent, it led to really unsightly long strings. 
            local f = math.random (1,20)
            if f == 1 then
               local letter = token.create'donothing'
 toks[n] = letter

            	elseif f == 2 then
               local letter = token.create'donothing'
 toks[n] = letter
 elseif f == 3 then
   local letter = token.create'donothing'  toks[n] = letter
 elseif f == 4 then
               local letter = token.create'twothings'
  toks[n] = letter
   elseif f == 5 then
   local letter = token.create'donothing'  toks[n] = letter

   else 
               local letter = token.create'onething'
 toks[n] = letter
            	end
            	elseif
            on and t.cmdname == "spacer" then
            local f = math.random (1,20)
            	if f == 2 then
               local letter = token.create'donothing'
 toks[n] = letter
         		            elseif f == 3 then
                    
               local letter = token.create'donothing'  toks[n] = letter
 elseif f == 4 then
 local letter = token.create'donothing'
  toks[n] = letter
           		            elseif f == 5 then
                    

               local letter = token.create'twothings'  toks[n] = letter
 elseif f == 6 then
                    

               local letter = token.create'donothing'  toks[n] = letter
                  elseif f == 7 then
   local letter = token.create'donothing'  toks[n] = letter


   else 
               local letter = token.create'onething'
 toks[n] = letter
 
            	end

            	elseif
            on and t.cmdname == "other_char" then
            local f = math.random (1,20)
            	if f == 2 then
               local letter = token.create'donothing'
 toks[n] = letter
         		            elseif f == 3 then
                    
               local letter = token.create'donothing'  toks[n] = letter
 elseif f == 4 then
 local letter = token.create'donothing'
  toks[n] = letter
           		            elseif f == 5 then
                    

               local letter = token.create'twothings'  toks[n] = letter
 elseif f == 6 then
                    

               local letter = token.create'donothing'  toks[n] = letter
                  elseif f == 7 then
   local letter = token.create'donothing'  toks[n] = letter


   else 
               local letter = token.create'onething'
 toks[n] = letter
 
            	end
                    end
    end
 --Drop the token in and move on
        token.put_next(toks)
end
local lft = lua.get_functions_table()
--make a global command
lft[#lft + 1] = rndstring
token.set_lua("rndstring", #lft, "global")
\end{luacode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% WARNING FUN YAY
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definitely this whole section
%is there to be user modified, because 
% depending on language, jurisdiction
%type of document etc, everyone will need
%a specific warning style. So the important
% part of the code here is the 
% conditional and global [warning]
% option, because that's the magic value added
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% fonts for the warning:
%I chose default LaTeX fonts
% here to be changed as users wish
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newfontface\wrnstncl{QT Military}
\newcommand{\warnword}{WARNING}
\newfontface\smbl{Deja Vu Sans Bold}
\newcommand{\danger}{\smbl ⚠︎\normalfont}
\newcommand{\warnformat}{\sffamily\bfseries \color{red}}
\newcommand{\textwarn}{This document is {\underline{NOT}}  redacted. It contains private and confidential personal data, and may {\underline{NOT}} be distributed, published, or shown to those without the right to view such information.  The publication of the information in this document may constitute a contempt of court, punishable by a term of imprisonment.}
\newcommand{\textsafe}{This document has been altered to remove sensitive personal data.  It is cleared for publication and dissemination.
}
\definecolor{darkgreen}{rgb}{0.0, 0.2, 0.13}
\definecolor{darkspringgreen}{rgb}{0.09, 0.45, 0.27}
	\definecolor{forestgreen}{rgb}{0.13, 0.55, 0.13}
\newcommand{\dquad}{\danger\danger\danger\danger}
\newcommand{\dangersign}[1]{\scalebox{2}{\huge\danger}}
\newcommand{\dangerblock}{\scalebox{2}{\huge\danger\quad\danger\quad\danger}}
\newcommand{\warnblock}{{\Large\wrnstncl\warnword\quad\warnword\quad\warnword}}
\newcommand{\tworules}{\hrule width \hsize height .7pt\vskip2pt\hrule width \hsize height .7pt}
\newcommand{\allwarning}{\dangerblock\\\warnblock\\\normalfont\smallskip\warnformat\textwarn }
\newcommand{\confwarning}{%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The warning option
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ifwarning
\ifcnsr 
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% a note saying document is redacted
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{center}
\color{forestgreen}
\tworules\vskip5pt
\normalsize\normalfont\sffamily\bfseries\textsafe
\vskip5pt\tworules
\end{center}
\else 
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The WARNING for un-redacted docs
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{center}\color{red}\tworules\vskip 5pt\allwarning
\vskip5pt\tworules%
\end{center}%
\fi%
\else\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Allow \maketitle
% on same page 
% yay
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ifwarning\let\oldmaketitle\maketitle\renewcommand{\maketitle}{{\let\newpage\relax\maketitle}}\else\fi
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% print the warning at the start of the document
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
\AtBeginDocument{\confwarning}