summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-02-19 21:21:07 +0000
committerKarl Berry <karl@freefriends.org>2022-02-19 21:21:07 +0000
commit7c9cb4484ce483546a0c249f172ac5588da7b35f (patch)
tree00d08d585724a4976b9aa6122d70a955b44484d7
parentf28a239e7f6ac2c19265821f88e93adee6c5c44f (diff)
luacensor (19feb22)
git-svn-id: svn://tug.org/texlive/trunk@62086 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/lualatex/luacensor/README12
-rw-r--r--Master/texmf-dist/doc/lualatex/luacensor/luacensor.pdfbin0 -> 129263 bytes
-rw-r--r--Master/texmf-dist/doc/lualatex/luacensor/luacensor.tex575
-rw-r--r--Master/texmf-dist/tex/lualatex/luacensor/luacensor.sty367
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-luatex.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/luacensor.tlpsrc0
7 files changed, 956 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/lualatex/luacensor/README b/Master/texmf-dist/doc/lualatex/luacensor/README
new file mode 100644
index 00000000000..6d737bcdacb
--- /dev/null
+++ b/Master/texmf-dist/doc/lualatex/luacensor/README
@@ -0,0 +1,12 @@
+luacensor - redacting sensitive information with Lua
+
+luacensor is a package that takes advantage of Lua to securely redact documents, both by hiding all characters and by slightly varying the length of strings to prevent jigsaw identification. It also is friendly to screen readers by adding alt-text indicating redacted content.
+
+See the documentation (luacensor.pdf) for examples and instructions for
+installation and usage.
+
+This work may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), version 1.3 or later.
+
+For suggestions, feature requests, and bug reports, please use the project's
+GitHub site: https://github.com/ezgranet/luacensor
diff --git a/Master/texmf-dist/doc/lualatex/luacensor/luacensor.pdf b/Master/texmf-dist/doc/lualatex/luacensor/luacensor.pdf
new file mode 100644
index 00000000000..3abd55551dd
--- /dev/null
+++ b/Master/texmf-dist/doc/lualatex/luacensor/luacensor.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/lualatex/luacensor/luacensor.tex b/Master/texmf-dist/doc/lualatex/luacensor/luacensor.tex
new file mode 100644
index 00000000000..9e2f1e14a0d
--- /dev/null
+++ b/Master/texmf-dist/doc/lualatex/luacensor/luacensor.tex
@@ -0,0 +1,575 @@
+\documentclass{article}
+\usepackage{xcolor}
+\usepackage[hidelinks]{hyperref}
+\usepackage[british]{babel}
+\usepackage[useregional]{datetime2}
+\DTMlangsetup[en-GB]{ord=omit}
+\definecolor{LightGray}{gray}{0.9}
+\usepackage{mathpazo}
+\usepackage{luacensor}
+\usepackage{fontspec}
+\IfFontExistsTF{Palatine Parliamentary}{\setromanfont[RawFeature={+onum,+pnum}]{Palatine Parliamentary}
+}{\setromanfont[RawFeature={+onum,+pnum}]{TeX Gyre PagellaX}}
+\setmonofont[Scale=.9]{Deja Vu Sans Mono}
+\usepackage{luacode}
+%\usepackage[firstnumber=last]{fancyvrb}
+\usepackage{minted}
+\date{\today}
+\author{Elijah Z Granet\thanks{e-mail: \href{mailto:ezg21@cantab.ac.uk}{ezg21@cantab.ac.uk}}}
+
+\title{\texttt{LuaCensor}:\\A package for redacting sensitive information}
+
+\begin{document}
+\maketitle
+\tableofcontents
+\section{Very Quick Guide}
+\subsection{Purpose}
+This package redacts sensitive information using \texttt{Lua}, and adds accessibility support.
+\subsection{Usage}
+The package is called with:
+
+\begin{minted}{latex}
+\usepackage{luacensor}
+\end{minted}
+
+Sensitive information is enclosed within the command:
+
+\begin{minted}{latex}
+\cnsr{John Smith}
+\end{minted}
+
+When the outputted document is intended for authorised readers who are supposed to see sensitive information, no further action is needed. When the outputted document is for general audiences, who are \textit{not} supposed to see sensitive information, add the following line to the preamble:
+
+\begin{minted}{latex}
+\cnsrtrue
+\end{minted}
+
+This activates the censoring globally.
+\subsection{Requirements}
+This package will \textbf{only} work in Lua\LaTeX. The package works out of the box with a standard \TeX\ distribution, but ideally, I would strongly suggest installing the free (\textit{libre} \& \textit{gratis}) `Redacted' font from Google Fonts, which gives a quite æsthetically pleasing black bar effect.\footnote{Available at: \url{https://fonts.google.com/specimen/Redacted}.}
+\subsection{\color{red}Warning}
+The package is completely effective at censoring text formatted with normal \LaTeX\ commands, by which I mean that it is impossible for someone to ascertain the original text (or even its precise length) from the outputted \MakeLowercase{\textsc{PDF}} when the \verb|\cnsrtrue| option has been activated.
+
+ However, math mode is used, it will censor numbers, but not operators or \TeX\ (as opposed to Unicode) operators. This is probably fine for most instances, but unacceptable where security is of the highest priority, and I would not really recommend using this package to censor highly secret formulæ; the \texttt{censor} package in your \TeX\ distribution will do a better job of that. The package is set to completely disappear the output (as opposed to black bar over) of the \texttt{math}, \texttt{align}, \texttt{equation}, \texttt{tabular}, and a few other environments, as disappearing these environments proved more secure than the piecemeal blacking out I saw. It is probable that there are packages and macros that will break the \texttt{cnsr} macro, and therefore, care should be taken to always examine output before public distribution.
+ \subsection{Demonstration}
+ \begin{quote}
+ \begin{minted}[fontsize=\footnotesize,
+,breaklines]{latex}
+%In the preamble: \usepackage{luacensor}
+\begin{quote}
+\cnsrtrue\footnotesize Whereas recognition of the \cnsr{inherent dignity and of the equal and inalienable rights of all members of the human family} is the foundation of freedom, justice and peace in the world,
+
+\cnsr{Whereas disregard and contempt for human rights have resulted in barbarous acts which have outraged the conscience of mankind, and the advent of a world in which human beings shall enjoy freedom of speech and belief and freedom from fear and want has been proclaimed as the highest aspiration of the common people,}
+ \end{minted}
+ \end{quote}
+ \begin{quote}
+\cnsrtrue\footnotesize Whereas recognition of the \cnsr{inherent dignity and of the equal and inalienable rights of all members of the human family} is the foundation of freedom, justice and peace in the world,
+
+\cnsr{Whereas disregard and contempt for human rights have resulted in barbarous acts which have outraged the conscience of mankind, and the advent of a world in which human beings shall enjoy freedom of speech and belief and freedom from fear and want has been proclaimed as the highest aspiration of the common people,}
+
+ \end{quote}
+
+ \clearpage
+
+
+
+\section{More detailed information}
+\subsection{Purpose}
+This package is a relatively lightweight and aesthetically pleasing censorship solution which includes accessibility features to allow screen readers to be aware that content has been redacted.
+\subsection{The censoring mechanism}
+The package uses Luas's \texttt{toks} filter to replace all \textsc{utf8} characters with a single glyph (• in the case of Redacted, and a Unicode black rectangle in the fallback \TeX\ default font Source Sans Pro). In both font options, these combine visually into a single line (though this can be deconstructed in a text editor).
+
+ However, while changing all characters into a single character is effective in \textit{most} cases, this alone would not be sufficiently secure for reliable usage. This is because knowing the length of a censored name could be combined with other information in, for example, a Family Court judgment, to allow for what lawyers call `jigsaw identification' (\textit{eg}, where there is only one person with an eight letter surname who meets the other details given in the judgment).
+
+Therefore, the package adds an extra layer of security by randomly changing the length of strings during the censorship phase; censored strings can thus be either longer or shorter by a few characters. This means that while the area of the blacked out content will be \textit{approximately} similar to the length of the uncensored string (which means wireframing more or less works), it cannot be used to reverse engineer information about the censored content.
+
+\subsection{The accessibility feature}
+One concern about document redaction is ensuring that visually impaired readers of your document, who use screen reading software to listen to your text, may encounter problems with censored content. If the screen reading software skips over the censored text altogether, it will be a very confusing jump for the visually impaired user. If the screen reading software reads the replacement characters, it will be very annoying for the visually impaired reader to hear, in a censored paragraph, the same character being read out \textit{ad nauseam} (\textit{eg}, `Asterisk, asterisk, asterisk…').
+
+To overcome this limitation, the package uses the \texttt{accsup} package to add an `actual text' feature which will lead screen readers (and utilities like \texttt{pdftotext}) to replace the string of replacement characters with the two words `TEXT REDACTED'. This also will be encountered by naïve users who try to outdo the package by copying and pasting the black blocks from Adobe™ Acrobat or Reader. (However, because other PDF readers, like Apple's Preview, do not implement accessibility features, this is \textbf{not} an additional security feature and is not on its own sufficient to work for redaction; if it were otherwise, the rest of the package would be unnecessary)
+
+
+
+\subsection{Bugs and development}
+All bugs, feature requests, or other technical points should be submitted to the package's official Github page.\footnote{\url{https://github.com/ezgranet/luacensor}}
+
+\subsection{Licensing}
+The software is free and open-sour ce software licensed under the Latex Public Project Licence.\footnote{\url{https://www.latex-project.org/lppl/}}
+
+
+\subsection{Some useful advice}
+This package is really good at some things, but if you find it breaks down on censoring complex \LaTeX\ code, the existing \texttt{censor} package on \textsc{ctan} is excellent (albeit less good with accessibility), and works with non-\texttt{Lua} versions of \TeX. Incidentally, you can use both this package and \texttt{censor} in the same file without trouble; this (\textit{not} a penchant for annoying tech-speak) is why the main command in this package is \texttt{cnsr} without vowels.
+
+\clearpage
+\section{Implementation}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]
+{latex}
+\ProvidesPackage{luacensor}
+[2022/02/17
+ Redact sensitive information using Lua]
+% 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
+\end{minted}
+\subsection{Dependencies}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]{latex}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% DEPENDENCIES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage{luacode}
+\RequirePackage{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's better for
+%the environment with printing
+\end{minted}
+\subsection{Fonts}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]{latex}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 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
+ItalicFont=Redacted,%
+BoldItalicFont=Redacted,%
+BoldFont=Redacted,%
+SmallCapsFont=Redacted]{Redacted}
+\newcommand{\onething}{\cnsrfnt\ • }
+\newcommand{\twothings}{\cnsrfnt\ • • }
+\newcommand{\donothing}{}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%The little spaces let justification happen
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% x 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}{}
+}
+\end{minted}
+
+
+
+\subsection{Eliminate pesky environments}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]{latex}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 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}
+
+\end{minted}
+\subsection{The \texttt{cnsr} command}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]{latex}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 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]{}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%TEX primitives can break the
+%code because they don't have the good manners
+%to put their arguments in brackets
+%No offence, of course, to the
+%honoured Prof Knuth, who had
+%magnificent genius reasons
+%for coding things that way
+%it's just that i'm an idiot
+%and therefore need things simple
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand{\hskip}[1]{}
+\renewcommand{\vskip}[1]{}
+\renewcommand{\raise}[1]{}
+\renewcommand{\lower}[1]{}
+\renewcommand{\kern}[1]{}
+% 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}
+\end{minted}
+\subsection{The Lua Magic}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]{latex}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The LUA MAGIC PART
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{luacode}
+\end{minted}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines,
+firstnumber=last
+]{lua}
+--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 = tfrue
+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{minted}
+\begin{minted}[
+frame=lines,
+framesep=2mm,
+baselinestretch=1.2,
+bgcolor=LightGray,
+fontsize=\footnotesize,
+linenos,
+breaklines, firstnumber=last
+]{latex}
+\end{luacode}
+\end{minted}
+\clearpage
+\section{Version History}
+\subsection{\texttt{1.00}}
+\ttfamily 18 February 2022: Package creation
+
+
+\end{document} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/lualatex/luacensor/luacensor.sty b/Master/texmf-dist/tex/lualatex/luacensor/luacensor.sty
new file mode 100644
index 00000000000..614378a56eb
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/luacensor/luacensor.sty
@@ -0,0 +1,367 @@
+%luacensor.sty
+\def\luacensorversionnumber{1.0.0}
+\ProvidesPackage{luacensor}
+[2022/02/18 \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
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 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's better for
+%the environment with printing
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 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
+ItalicFont=Redacted,%
+BoldItalicFont=Redacted,%
+BoldFont=Redacted,%
+SmallCapsFont=Redacted]{Redacted}
+\newcommand{\onething}{\cnsrfnt\ • }
+\newcommand{\twothings}{\cnsrfnt\ • • }
+\newcommand{\donothing}{}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%The little spaces let justification happen
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% x 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]{}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%TEX primitives can break the
+%code because they don't have the good manners
+%to put their arguments in brackets
+%No offence, of course, to the
+%honoured Prof Knuth, who had
+%magnificent genius reasons
+%for coding things that way
+%it's just that i'm an idiot
+%and therefore need things simple
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand{\hskip}[1]{}
+\renewcommand{\vskip}[1]{}
+\renewcommand{\raise}[1]{}
+\renewcommand{\lower}[1]{}
+\renewcommand{\kern}[1]{}
+% 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} \ No newline at end of file
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 0c5ad1e5bcc..4192448f611 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -494,7 +494,7 @@ my @TLP_working = qw(
ltxkeys ltxmisc ltxnew ltxtools
lua-alt-getopt lua-check-hyphen lua-physical lua-typo lua-uca lua-ul
lua-uni-algos lua-visual-debug lua-widow-control
- luabibentry luabidi luacode luacolor luafindfont luahyphenrules
+ luabibentry luabidi luacensor luacode luacolor luafindfont luahyphenrules
luaimageembed luaindex luainputenc luaintro luakeys
lualatex-doc lualatex-doc-de
lualatex-math lualatex-truncate lualibs
diff --git a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
index 9a98a1e157e..e1534bda171 100644
--- a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
@@ -29,6 +29,7 @@ depend lua-uni-algos
depend lua-ul
depend lua-visual-debug
depend lua-widow-control
+depend luacensor
depend luacode
depend luacolor
depend luahyphenrules
diff --git a/Master/tlpkg/tlpsrc/luacensor.tlpsrc b/Master/tlpkg/tlpsrc/luacensor.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/luacensor.tlpsrc