% \iffalse
% File: qrcodetikz.dtx
% Copyright (C) 2025 Miguel V. S. Frasson (mvsfrasson@gmail.com)
%
% This package may be distributed under the terms of the LaTeX
% Project Public License, as described in lppl.txt in the base
% LaTeX distribution, either version 1.3 or (at your option)
% any later version.
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{hyperref}
\hypersetup{
    colorlinks,
    linkcolor={blue!50!black},
    citecolor={black},
    urlcolor={black}
}
\usepackage{doc,amsmath,enumitem,mathabx,array,booktabs,wasysym}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{microtype}
\usepackage[nolinks]{qrcodetikz}
\usepackage{tikz}
\usetikzlibrary{arrows,arrows.meta}
\makeatletter
\newcommand{\nDescribeMacro}[1]{%
  \xa\xa\xa\DescribeMacro\xa\csname\xa\@gobble\string#1\endcsname\ignorespaces}%
\makeatother
\begin{document}
  \DocInput{qrcodetikz.dtx}
\end{document}
%</driver>
% \fi
%
% \def\exclamacao{!}
% \MakeShortVerb\!
% \def\vars#1{\textlangle\textit{#1}\textrangle}
% \def\markpage#1{\refstepcounter{enumiv}\label{#1}}
%
% \title{\textbf{qrcodetikz}: prettier \textsc{qr} codes}
% \author{Miguel Vinícius Santini Frasson\\ \texttt{mvsfrasson@gmail.com}}
% \date{2025--05--28, version 1.0}
%
% \noindent
% \raisebox{-4mm}{%
%   \qrcode[link,height=1in]{https://ctan.org/pkg/qrcodetikz}}\qquad
% \begin{minipage}[c]{0.65\linewidth}
%   \maketitle
% \end{minipage}
%
% \tableofcontents
%
% \section{Introduction}
%
% The package \href{https://ctan.org/pkg/qrcodetikz}{\texttt{qrcodetikz}}
% aims to improve the display of QR codes provided by package
% \href{https://ctan.org/pkg/qrcode}{\texttt{qrcode}}.
%
% \begin{center}
%   \begin{tabular}{l@{\qquad}c@{\qquad}l}
%     {\qrcodetikzOff\qrcode[height=2cm]{QR codes}} & vs.
%     & \qrcodetikzOn\qrcode[height=2cm]{QR codes}\\[0.35in]
%     with \texttt{qrcode} & &
%     with \texttt{qrcodetikz}
%   \end{tabular}
% \end{center}
%
% The Quick Response (QR) codes provided by package \texttt{qrcode}
% show white borders on each square (from little to very proeminent
% depending on pdf viewer).  This is because the QR code is printed
% square by square, not the connected regions of squares as such, and
% pdf screen viewers show these undesired square borders.
%
% This package overwrites the \texttt{qrcode} printing functions to
% fill connected regions of the QR code using Ti\textit{k}Z, allowing
% prettier qrcodes on screen visualization, with possibility of
% customization.
%
% \section{Usage}
%
% To switch the display of QR codes with Ti\textit{k}Z, just load
% package \texttt{qrcodetikz} instead of \texttt{qrcode}.  The package
% options are the same of \texttt{qrcode} package\footnote{All options
% are passed to \texttt{qrcode} package.}, that we repeat briefly (for
% details, see \texttt{qrcode} documentation):
% \begin{description}
% \item[nolinks] disable qrcode links if \texttt{hyperref} is loaded.
% \item[draft] doesn't compute QR codes, dummy QR codes are
%   displayed, like
%   \raisebox{\depth}[0pt]{\qrcode[draft,version=2,height=1.5cm]{ABCD}}
%
% \item[final] opposite to draft, display complete QR codes.
% \item[forget] do not store QR codes into \texttt{.aux} for reusage,
% recompute them in every run (mainly for debug purposes).
% \end{description}
%
% You can set other options using
% \texttt{\string\qruse\{\textit{\vars{options}}\}}, which can be set
% as options to !\qrcode! command. These options are:
% \begin{description}
% \item[height=\vars{dimension}] sets the height (and width) of the QR
% codes. Default is 2~cm;.
% \item[level=\vars{L-M-Q-H}] sets the level of error correction; the
% levels are set with one letter: \texttt{L} (low), \texttt{M} (medium),
% \texttt{Q} (quality) and \texttt{H} (high). Default is \texttt{M}.
% \item[version=\vars{1-to-40}] is related to the size if the QR code.
%   Must be a number between 1 and 40.  Default is the lowest version
%   that encodes text with desired quality.
% \item[padding, tight] QR code specification says that a QR code should be
% surrounded by some white space (specifically the width of 4
% modules).  With \texttt{padding}, this white border is added.  With
% \texttt{tight}, this white border is omitted, since it is usually
% provided by the user. Defult to \texttt{tight}.
% \item[link, nolink] Allows/disallows use of clickable links with the
% QR code.
% \end{description}
%
% For many more details, like special characters, please refer to the
% documentation of \texttt{qrcode} package.
%
% \subsection{Fill options}
%
% \DescribeMacro{\qrcodeFillOptions}
% The default plain QR codes are fine and recommended.  However, with
% \texttt{qrcodetikz}, the user can pass fill options !\fill! command
% to display the QR codes, like colors, rounded corners, shades,
% etc. using
% \begin{center}
%   \texttt{\string\qrcodeFillOptions\{\vars{fill-options}\}}
% \end{center}
% The settings persist until the next call of !\qrcodeFillOptions!
% (for example, a call of !\qrcodeFillOptions{}! erases previous
% customizations).  As an example:\medskip
%
% \DeleteShortVerb\|\DeleteShortVerb\!\MakeShortVerb\+
% \noindent
% +\begin{center}+\\
% +  +\texttt{\textit{\% rounded corners}}\\
% +  \qrcodeFillOptions{rounded corners=1pt}+\\
% +  \qrcode{QR codes}\qquad+\\
% +  +\texttt{\textit{\% shades}}\\
% +  \qrcodeFillOptions{left color=gray,right color=black,draw=black,thin}+\\
% +  \qrcode{QR codes}\qquad+\\
% +  +\texttt{\textit{\% removing customization}}\\
% +  \qrcodeFillOptions{}+\\
% +  \qrcode{QR codes}+\\
% +\end{center}+\DeleteShortVerb\+\MakeShortVerb\!
%
% \noindent would print:
%
% \begin{center}
%   \qrcodeFillOptions{rounded corners=1pt}
%   \qrcode{QR codes}\qquad
%   \qrcodeFillOptions{left color=gray,right color=black,draw=black,thin}
%   \qrcode{QR codes}\qquad
%   \qrcodeFillOptions{}
%   \qrcode{QR codes}\refstepcounter{enumiv}\label{qrcode-bug}
% \end{center}
%
% Notice that last qrcode was printed plain, without customizations.
%
% In our humble opinion, plain QR codes are prettier.  The
% implementation made an effort to produce good looking QR codes with
% fill option !rounded corners!, filling individual connected
% components of the QR code to avoid straight corners.  Other
% customizations with fill options are left for the convenience of the
% user.\medskip
%
% \DescribeMacro{\qrcodetikzOn}\DescribeMacro{\qrcodetikzOff}
% One can turn on and off QRcodes with Ti\textit{k}Z with commands
% \texttt{\string\qrcodetikzOn} and \texttt{\string\qrcodetikzOff}.
% When turned off, original \texttt{qrcode} functions for printing are
% restored.  These functions probably will never be used outside this
% manual \smiley.
%
% This package was not intended specifically to display artistic QR
% codes. For that you can take a look into
% \href{https://ctan.org/pkg/fancyqr}{\texttt{fancyqr}} package.
%
% For the regular user, the documentation ends here.  In the following
% pages we give details of the implementation.
%
% \section{Implementation}
%
% \subsection{Ideas and conventions}
%
% Using the \texttt{qrcode} package, that saves computed QR codes into
% the \texttt{.aux} file, if one calls !\qrcode{QrCode}!, we get into
% the \texttt{.aux} file the line below (as a long line without
% linebreaks):\medskip
%
% \noindent\texttt{\small\string\qr@savematrix\{QrCode\}\{1\}\{2\}\{\relax
% 1111111010000011111111000001000100010000011011\\
% 101010000010111011011101000100010111011011101010101010111011000001001010010\\
% 000011111111010101011111110000000011000000000000000011001011010101011011100\\
% 111100110101100000111000100010100100101100010111010111101011001110010010011\\
% 110000000011110110001101111111000001111010101000001010100001111001011101000\\
% 010100000101011101001011110110001011101001001010100111000001000001110011001\\
% 11111100000101000010\}}\medskip
%
% Counting the 0's and 1's, we get $441=21^2$ “bits”. Dividing the string into
% 21 lines of 21 bits, coloring 1's as black boxes and 0's as light boxes
% to ease visualization we get:\medskip
%
% \begin{center}
%   \scalebox{0.7}{\begin{minipage}[c]{0.606\linewidth}
%     \footnotesize
%     \def\1{\colorbox{black}{\textcolor{white}{1}}}\relax
%     \def\0{\colorbox{white}{\textcolor{black}{0}}}\ttfamily
%     \1\1\1\1\1\1\1\0\1\0\0\0\0\0\1\1\1\1\1\1\1\\
%     \1\0\0\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\0\0\1\\
%     \1\0\1\1\1\0\1\0\1\0\0\0\0\0\1\0\1\1\1\0\1\\
%     \1\0\1\1\1\0\1\0\0\0\1\0\0\0\1\0\1\1\1\0\1\\
%     \1\0\1\1\1\0\1\0\1\0\1\0\1\0\1\0\1\1\1\0\1\\
%     \1\0\0\0\0\0\1\0\0\1\0\1\0\0\1\0\0\0\0\0\1\\
%     \1\1\1\1\1\1\1\0\1\0\1\0\1\0\1\1\1\1\1\1\1\\
%     \0\0\0\0\0\0\0\0\1\1\0\0\0\0\0\0\0\0\0\0\0\\
%     \0\0\0\0\0\1\1\0\0\1\0\1\1\0\1\0\1\0\1\0\1\\
%     \1\0\1\1\1\0\0\1\1\1\1\0\0\1\1\0\1\0\1\1\0\\
%     \0\0\0\0\1\1\1\0\0\0\1\0\0\0\1\0\1\0\0\1\0\\
%     \0\1\0\1\1\0\0\0\1\0\1\1\1\0\1\0\1\1\1\1\0\\
%     \1\0\1\1\0\0\1\1\1\0\0\1\0\0\1\0\0\1\1\1\1\\
%     \0\0\0\0\0\0\0\0\1\1\1\1\0\1\1\0\0\0\1\1\0\\
%     \1\1\1\1\1\1\1\0\0\0\0\0\1\1\1\1\0\1\0\1\0\\
%     \1\0\0\0\0\0\1\0\1\0\1\0\0\0\0\1\1\1\1\0\0\\
%     \1\0\1\1\1\0\1\0\0\0\0\1\0\1\0\0\0\0\0\1\0\\
%     \1\0\1\1\1\0\1\0\0\1\0\1\1\1\1\0\1\1\0\0\0\\
%     \1\0\1\1\1\0\1\0\0\1\0\0\1\0\1\0\1\0\0\1\1\\
%     \1\0\0\0\0\0\1\0\0\0\0\0\1\1\1\0\0\1\1\0\0\\
%     \1\1\1\1\1\1\1\0\0\0\0\0\1\0\1\0\0\0\0\1\0
%   \end{minipage}}\qquad
%   \begin{tabular}{c}
%     {\qrcodetikzOff\qrcode[height=5cm]{QrCode}}\\[2.7cm]
%     (printed with \texttt{qrcode})
%   \end{tabular}
%
%   \mbox{}
% \end{center}
%
% So one sees that the binary data must be printed in rows from left
% to right, from top to bottom.  On the right of the picture above it
% is the QR code as printed with the \texttt{qrcode} package: it
% prints individual black squares for each 1 and equivalent space for
% 0.  An unpleasant side effect are the visible thin borders of squares
% when pdf file is visualized on screen.  This package is meant to fix
% this, printing regions as a whole with Ti\textit{k}Z.
%
% We observed that if we make a path connecting all connected borders
% of the pixels, and fill this path with the “even-odd
% rule”\,\footnote{The SVG defines the even-odd rule by saying: “This
% rule determines the ‘insideness’ of a point on the canvas by drawing
% a ray from that point to infinity in any direction and counting the
% number of path segments from the given shape that the ray
% crosses. If this number is odd, the point is inside; if even, the
% point is outside.”
% (\href{https://en.wikipedia.org/wiki/Even–odd_rule}{\relax
% \texttt{https://en.wikipedia.org/wiki/Even–odd\_rule}}).}, it would
% beautifully print the QRcode.
%
% \begin{center}
%   \begin{tikzpicture}[scale=1.5]
%     \draw (0,0) rectangle (0.7,0.7) (0.1,0.1) rectangle (0.6,0.6)
%     (0.2,0.2) rectangle (0.5,0.5);
%     \draw[>=stealth',->] (1,0.35) -- ++(0.7,0);
%     \fill[even odd rule,xshift=2.1cm] (0,0) rectangle
%     (0.7,0.7) (0.1,0.1) rectangle (0.6,0.6) (0.2,0.2) rectangle
%     (0.5,0.5);
%   \end{tikzpicture}\medskip
%
%   Fill with even-odd rule.
% \end{center}
%
% This package is the implementation of such idea.  We took advantage
% of facilities from \LaTeX3 such as loops, sequences (lists), arrays
% of integers, property lists, easy integer computations and other
% goodies already loaded into the \LaTeX\ kernel in every run in any
% recent \TeX\ distribution.  The only external packages needed are
% \texttt{qrcode} (to compute the qrcode) and \texttt{tikz} (to fill a
% path in even-odd rule).
%
% If any other package wants to take advance of the conversion (binary
% data) $\leftrightarrow$ (Ti\textit{k}Z path), for artistic
% reasons for instance, could use\\
% !  \QRTZgetTikzPathMaybeSaved!\texttt{\{\vars{binary data}\}\{\vars{cmd to store path}\}}\\
% explained in section~\ref{sec:prop}, that tries to reuse computed
% paths or computes it otherwise.  The first argument is expanded, so
% it can be a command that holds the binary data.
%
% In QRcode jargon, the size in number of squares of the QR code is
% given by its \textit{version}.  This size is
% $4 \times \text{\vars{qrcode version}} + 17$.  The maximum version
% os 40, so the maximum size is $4\times40+17 = 177$.  We take advance
% of integer arrays in \LaTeX3 (module \textsf{l3intarray}) that
% provide fast access to any integer in the array and store all
% matrices $n\times n$ as linear sequence of $n^2$ integers, in the
% order as the binary data.
%
% As Ti\textit{k}Z uses cartesian coordinates, we decided to use them
% as the coordinates of the pixels.  We implement the conversion from
% $(x,y)$ coordiante, with $x$ and $y$ from $1$ to $n$, to sequence
% index from $1$ to $n^2$ so that
% \begin{itemize}[itemsep=0pt,parsep=0pt]
% \item pixel $(1,n)$ – top left – is in index $1$;
% \item pixel $(n,n)$ – top right – is in index $n$;
% \item pixel $(n,n)$ – bottom right – is in index $n^2$;
% \item pixel $(1,1)$ – bottom left – is in index $(n-1)n + 1$.
% \end{itemize}
% Doing the math, index is $(n-y)n + x$.\medskip
%
% We need to put a convention to the coodinates of the corners.  We
% define that a pixel $(x,y)$ gives its coordinates to the bottom-left
% corner.  The coordinates of the lines vary from 1 to $n+1$.  This
% way, the size of the smallest line segment is 1 and the size of a QR
% code is a square of size $n$, so the path must be scaled down to fit
% the required size of the QR code.
%
% With these conventions, we can begin implementation according the
% following steps:
%
% \begin{enumerate}
% \item We store the binary matrix into a array of integers; we use
%   intarrays from \LaTeX3 to get fast read/write access. The
%   interface $(x,y) \leftrightarrow i$ (array index) is explained in
%   section~\ref{sec:matrix}.  At this point, every pixel is stored as
%   values 0 (for empty) or 1 (for black).
% \item We compute the connected components of the QR code using
%   “find/union” operations, a fast algorithm, explained in
%   section~\ref{sec:cc}.  The content of the pixel will be 0 (for
%   empty) or a positive integer that labels the connected component,
%   shared by all pixels in that same connected component.  A positive
%   value will be printed as black.
% \item We build a list of all borders of pixels.  We have to fix
%   notation for a border: after some reimplementations\footnote{After
%   first successful implementation, we realized that \texttt{rounded
%   corners} fill option produced ugly straight crossings so we
%   decided to implement connected components and follow the path
%   always inward in a crossing with multiple ways.  A natural choice
%   as to walk the borders in “positive” sense according to Calculus
%   rules, that is, interior is always on the left, so inward means
%   turn left in most cases.  After some reasoning, we came up with
%   the directions 0 to 3, so turn left means add 1 modulus 4 and turn
%   right means add $-1$ modulus 4.}, we came up with the notation of
%   border as a comma list $x,y,d,c$ where $(x,y)$ is the origin of
%   the border, $d$ is a direction number from 0 to 3 (representing
%   angle $d\cdot 90$°): 0 ($\rightarrow$), 1 ($\uparrow$), 2
%   ($\leftarrow$), 3 ($\downarrow$) in such way that the black pixel
%   is always to the left of the border and $c$ is the number of the
%   connected component that such pixel belongs to.  Following a
%   border to the next in the same connected component will walk the
%   border in “positive” direction (counterclockwise), and in a
%   crossing, turn left (that is, add 1 modulus 4) will always turn
%   inward.  The process of creating the list of borders is described
%   in section~\ref{sec:borders}.
%
% \item Now we build the Ti\textit{k}Z path, the main part of the
%   package.  Starting from any border, the next border is either turn
%   left (inward), go straight or turn right in the same connected
%   component, trying in this sequence.  Every walked border is
%   removed from the list of borders.  In the beginning and at every
%   turn, output “$(x,y)$-{}-” to the path, where $(x,y)$ is the
%   origin of the border.  When none of these borders is in the list,
%   we arrive at a dead end and output “cycle” to the path.  This
%   pocess is reeated while the list of borders is not empty.  This
%   algorithm is implemented in section~\ref{sec:path}.
%
% \item The package \texttt{qrcode} saves the correspondence
%   “text+version” $\leftrightarrow$ “binary data” into the aux file,
%   and at beginning of document, this code saves the binary data as a
%   macro, avoiding most of the computation.  For the computed
%   Ti\textit{k}Z paths we implement this saving/restoring as a
%   \LaTeX3 prop list, also saving the correspondence “binary data”
%   $\leftrightarrow$ “path” into the aux file.  This is done in
%   section~\ref{sec:prop}.
%
% \item In the mood of \texttt{qrcode} package, we save into the aux
%   file a line that populates the prop list from previous item.  This
%   is done in section~\ref{sec:aux}.
%
% \item In section \ref{sec:print} we implement functions that are
%   meant to replace \texttt{qrcode} functions: that package
%   implements matrices as a series of macros.  Fortunately
%   \texttt{qrcode} has a function to convert its matrices as binary
%   data.  To avoid any change of behavior and get the closest result
%   from \texttt{qrcode}, we copied most of the computations plainly
%   from that package, but printing the path with Ti\textit{k}Z
%   instead of the original display of individual boxes.
%
% \item Finally, in section \ref{sec:on-off} we save copies of former functions
%   and implement turning on and off of new printing functions.
% \end{enumerate}
%
% \subsection{Package identification}
%
% This package uses \LaTeX3 interface, with most recently implemented
% functions in \textsf{l3intarray} module from 2018.  In
% 2020\footnote{See
% \url{https://www.latex-project.org/news/latex2e-news/}, entry for
% 2020/02/02.}, \LaTeX3 was included into \LaTeXe{}, so we require
% \LaTeXe{} version at least as recent as 2020.  If you only have
% access to ealier versions of \LaTeXe, you can use
% !\usepackage{expl3}!, but we still depend on \LaTeX3
% \textit{intarray} module from 2018.
%
% This package passes all options to \texttt{qrcode} package and loads
% it, if not already loaded.
%
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[2020-02-02]
\ProvidesPackage{qrcodetikz}[2025-05-28 v1.0 Prettier qrcodes]
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{qrcode}}
\ProcessOptions
\RequirePackage{qrcode}
\RequirePackage{tikz}
%    \end{macrocode}
%
% The package uses \LaTeX3 in most of its extension.  Only the final
% printing functions that will replace \texttt{qrcode} printing
% functions don't use \LaTeX3.
%    \begin{macrocode}
\ExplSyntaxOn
%    \end{macrocode}
%
% \subsection{Declaration of variables}
%
% We declare some few variables.  Variables of type “token list”
% should end with the suffix !_tl!, but we decided to ommit it for
% readability.
%
% \begin{itemize}
% \item Integer variable !\l_qrtz_size_int! holds the size of the side
%   of QR code.
%    \begin{macrocode}
\int_new:N \l_qrtz_size_int
%    \end{macrocode}
%
% \item Individual coordinates of $(x,y)$ are stored in
%    \begin{macrocode}
\tl_new:N \l_qrtz_x
\tl_new:N \l_qrtz_y
%    \end{macrocode}
%
% \item The direction number (0 to 3) is stored in
%    \begin{macrocode}
\tl_new:N \l_qrtz_dir
%    \end{macrocode}
%
% \item The number of current connected component is stored in
%    \begin{macrocode}
\tl_new:N \l_qrtz_component
%    \end{macrocode}
%
% \item Current path in construction is stored in
%    \begin{macrocode}
\tl_new:N \l_qrtz_path
%    \end{macrocode}
%
% \item Borders are stored in
%    \begin{macrocode}
\tl_new:N \l_qrtz_border
\tl_new:N \l_qrtz_inner
\tl_new:N \l_qrtz_straight
\tl_new:N \l_qrtz_outer
%    \end{macrocode}
%
% \item \LaTeX3 intarray that stores matrix. Its size is $177^2=31\,329$,
% the worst possible case.
%    \begin{macrocode}
\intarray_new:Nn \g_qrtz_labels_intarray {177 * 177}
%    \end{macrocode}
%
% \item \LaTeX3 sequence to store the list of borders
%    \begin{macrocode}
\seq_new:N \l_qrtz_border_seq
%    \end{macrocode}
%
% \item \LaTeX3 property list that stores saved information (binary-data
% $\leftrightarrow$ path correspondence)
%    \begin{macrocode}
\prop_new:N \g_qrtz_paths_prop
%    \end{macrocode}
%
% \item Switch for fallback definition of .aux commands
%    \begin{macrocode}
\bool_new:N \g_qrtz_aux_fallback_written_bool
\bool_gset_false:N \g_qrtz_aux_fallback_written_bool
%    \end{macrocode}
%
% \item Auxiliary switches
%    \begin{macrocode}
\bool_new:N \l_qrtz_continue_straight_bool
\bool_new:N \l_qrtz_can_continue_bool
%    \end{macrocode}
% \end{itemize}
%
% \subsection{Interface for matrix and intarray correspondence }
% \label{sec:matrix}
%
% \nDescribeMacro{\qrtz_index:nn}
% Pixel $(x,y)$ corresponds to index $(n-y)n+x$ on the intarray.
% Function !\qrtz_index:nn {!\vars{x}!}{!\vars{y}!}!
% returns the linear index of a pixel in coordinates $(x,y)$.
% Size is stored in !\l_qrtz_size_int!.
% \nDescribeMacro{\qrtz_pixel:nn}
% Function !\qrtz_pixel:nn {!\vars{x}!}{!\vars{y}!}! returns the value
% of the entry, that is, 0 for white pixel, positive (the connected
% component number) if black.
%    \begin{macrocode}
\cs_new:Nn \qrtz_index:nn {
  ( \l_qrtz_size_int - (#2) ) * \l_qrtz_size_int + (#1)
}
%
\cs_new:Nn \qrtz_pixel:nn {
  \intarray_item:Nn \g_qrtz_labels_intarray { \qrtz_index:nn {#1}{#2} }
}
%    \end{macrocode}
%
% \subsection{Computation of connected components}
% \label{sec:cc}
%
% We use \textit{union-find algorithm} to compute connected
% components. The idea is that every pixel is a node in a graph, and a
% pointed connection $A \to B$ means that “$B$ is parent of $A$”.  If
% $A$ points to itself, it means that $A$ is a “patriarch”.  Two nodes
% $A$ and $B$ belong to the same family if they share the same patriarch.
%
% For example, consider the pointed graph
% \[
%   1 \to
%   \begin{array}[b]{c}
%     3\\ \downarrow\\2
%   \end{array}
%   \to 4 \righttoleftarrow,\quad
%   5 \righttoleftarrow,
%   \quad 6 \to 7 \to 8 \righttoleftarrow
% \]
%
% The patriarchs are 4, 5 and 8. The families (\textit{i.e.},
% connected components) are $\{1,2,3,4\}$, $\{5\}$ and $\{6,7,8\}$.
%
% There are two functions: \textit{find} that returns the patriarch of
% an element, and \textit{union} that joins two families, making a
% former patriarch to point another node in another family (otherwise
% we get a cycle), joining the families under one of the patriarchs.
% A way to avoid cycles is to make a patriarch to point another patriarch.
%
% We implement the “pointing” as the result of an array $A[i]=j$,
% meaning $i \to j$.
%
% The graph above is represented by the array:
% \begin{center}
%   \begin{tabular}{@{}c*{8}{c}@{}}
%     \toprule
%     $i$ & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ \midrule
%     $A[i]$ & 2 & 4 & 2 & 4 & 5 & 7 & 8 & 8 \\ \bottomrule
%   \end{tabular}
% \end{center}
%
% \begin{itemize}
% \item find($i$): $j\leftarrow i$. while $A[j]\neq j$ do: $j \leftarrow A[j]$. Return $j$.
%
% \item union($i,j$): $A[\text{find}(i)] \leftarrow \text{find}(j)$.
% \end{itemize}
%
% We initialize the array with $A[i]=i$ if pixel is black or $A[i]=0$
% otherwise, for all $i$ (all black pixels are disconnected).
%
% \textit{First pass}: Loop through all pixels $x,y$, that correspond to index
% $i$.  If a pixel $p$ is black: if pixel $q$ to the right of $p$ is
% also black, perform union($p,q$); if pixel $q$ below $p$ is
% also black, perform union($p,q$).
%
% At the end of first pass, all connected components are determined.
% It remains to clearly label the component of each pixel, doing the
% second pass:
%
% \textit{Second pass}: loop for all indexes $i$:
% $A[i] \leftarrow \text{find(i)}$.
%
% Now each pixel $p$, which has index $i$\footnote{The index of a
% pixel $(x,y)$ is given by function \texttt{\string\qrtz\_index:nn
% \{\textit{x}\} \{\textit{y}\}}.}, belongs to component $c = A[i]$.
% Below we implement that.  The array $A$ is the variable
% !\g_qrtz_labels_intarray!.
%
% \nDescribeMacro{\qrtz_find:nnN}
% Implementation of find: !\qrtz_find:nnN {!\vars{x}!}{!\vars{y}!} #3!.
% Last arg \texttt{\#3} should be an integer var (module \textsf{l3int}) that
% will receive the index of the patriarc of $(x,y)$.
%    \begin{macrocode}
\cs_new:Nn \qrtz_find:nnN {
  \int_set:Nn #3 { \qrtz_index:nn {#1}{#2} }
  \int_until_do:nNnn {\intarray_item:Nn \g_qrtz_labels_intarray #3} = #3
  {
    \int_set:Nn #3 {\intarray_item:Nn \g_qrtz_labels_intarray #3}
  }
}
%    \end{macrocode}
%
% % \nDescribeMacro{\qrtz_union:nnnn}
% Implementation of \textit{union} of pixels $(x_0,y_0)$ and $(x_1,y_1)$.
%    \begin{macrocode}
\cs_new:Nn \qrtz_union:nnnn {
  \qrtz_find:nnN {#1}{#2} \l_tmpa_int
  \qrtz_find:nnN {#3}{#4} \l_tmpb_int
  \intarray_gset:Nnn \g_qrtz_labels_intarray \l_tmpb_int \l_tmpa_int
}
%    \end{macrocode}
%
% \nDescribeMacro{\qrtz_compute_components:n}
% A function that performs the two passes of the
% algorithm described above. Its argument \texttt{\#1} is the binary
% data of the QR code, loaded into the intarray
% !\l_qrtz_labels_intarray!: 1 becomes the index $i$, 0 remains 0.
% Index will be stored in !\l_tmpa_int!
%    \begin{macrocode}
\cs_new:Nn \qrtz_compute_components:n {
  \int_zero:N \l_tmpa_int
  \tl_map_inline:nn {#1}
  {
    \int_incr:N \l_tmpa_int
    \intarray_gset:Nnn
    \g_qrtz_labels_intarray { \l_tmpa_int } { ##1 * \l_tmpa_int }
  }
%    \end{macrocode}
% Set matrix size $n$ as $n\leftarrow \sqrt{l}$,
% where $l=\text{\textit{length}}$ is stored in !\l_tmpa_int! after
% previous loop.
%    \begin{macrocode}
  \int_set:Nn \l_qrtz_size_int { \fp_to_int:n { sqrt( \l_tmpa_int ) } }
%    \end{macrocode}
%
% \textit{First pass}: Iterate $x$,$y$ from 1 to
% !\l_qrtz_size_int! (size of side of % QRcode);
% if (it make sense pixel at right of $(x,y)$) \textit{and}
% (current pixel is black) \textit{and} (pixel to the right is black)
% [“and” computed with !lazy_all!, that is, one false condition stops
% evaluation, returns false], do union operation of these pixels.  The
% analogue conditions for pixel below current pixel.
%    \begin{macrocode}
  \int_step_inline:nn { \l_qrtz_size_int } { % i=##1
    \int_step_inline:nn { \l_qrtz_size_int } { % j = ####1

      \bool_if:nT {
        \bool_lazy_all_p:n {
          { \int_compare_p:nNn {##1} < \l_qrtz_size_int }
          { \int_compare_p:nNn { \qrtz_pixel:nn {##1}{####1} } > 0 }
          { \int_compare_p:nNn { \qrtz_pixel:nn {1 + ##1}{####1} } > 0 }
        }
      }
      { \qrtz_union:nnnn {##1}{####1} {1 + ##1}{####1} }

      \bool_if:nT {
        \bool_lazy_all_p:n {
          { \int_compare_p:nNn {####1} < \l_qrtz_size_int }
          { \int_compare_p:nNn { \qrtz_pixel:nn {##1}{####1} } > 0 }
          { \int_compare_p:nNn { \qrtz_pixel:nn {##1}{1 + ####1} } > 0 }
        }
      }
      { \qrtz_union:nnnn {##1}{####1} {##1}{1 + ####1} }
    }
  }
%    \end{macrocode}
%
% \textit{Second pass}: if pixel is black, set its value as its
% patriarch (find operation).  !\l_tmpa_int! holds index of current
% pixel, !\l_tmpb_int! holds index of its patriarch.
%    \begin{macrocode}
  \int_step_inline:nn { \l_qrtz_size_int } { %   i = ##1
    \int_step_inline:nn { \l_qrtz_size_int } { % j = ####1

      \int_set:Nn \l_tmpa_int { \qrtz_index:nn {##1} {####1} }

      \int_compare:nNnF
      {\intarray_item:Nn \g_qrtz_labels_intarray \l_tmpa_int} = 0
      {
        \qrtz_find:nnN {##1} {####1} \l_tmpb_int
        \intarray_gset:Nnn \g_qrtz_labels_intarray \l_tmpa_int \l_tmpb_int
      }
    }
  }
}
%    \end{macrocode}
%
% \subsection{Construction of the list of borders}
% \label{sec:borders}
%
% We decided that a border is a comma list $x,y,d,c$ where $(x,y)$ is
% the origin of the border, $c$ is the number of the connected
% component of the pixel to which this border corresponds and $d$ is
% one of the numbers $0$, $1$, $2$ or $3$ meaning the direction
% $d\cdot 90\text{°}$, with the convention that the interior (black
% pixel) in on the left of the border, so that when one walks by
% subsequent borders, the path is walked in positive sense,
% \textit{i.e.}, counterclockwise.
% \begin{center}
%   \begin{tikzpicture}[>=stealth']
%     \draw (0,0) rectangle (6,6);
%     \fill[gray!30!white,draw=gray]
%     (0,2.5) coordinate (r1) rectangle ++(1,1)
%     (6,2.5) coordinate (r2) rectangle ++(-1,1)
%     (3,0) coordinate (r3) rectangle ++(1,1)
%     (3,6) coordinate (r4) rectangle ++(1,-1)
%     (r1-|r3) coordinate (r5) rectangle ++(1,1) coordinate (r6);
%     \draw
%     (r1) ++(0.5,0.5) node {\parbox{1cm}{\centering{\footnotesize pixel}\\$1,y$}}
%     (r2) ++(-0.5,0.5) node {\parbox{1cm}{\centering{\footnotesize pixel}\\$n,y$}}
%     (r3) ++(0.5,0.5) node {\parbox{1cm}{\centering{\footnotesize pixel}\\$x,1$}}
%     (r4) ++(0.5,-0.5) node {\parbox{1cm}{\centering{\footnotesize pixel}\\$x,n$}}
%     (r5) ++(0.5,0.5) node {\parbox{1cm}{\centering{\footnotesize pixel}\\$x,y$}};
%
%     \draw[very thick,red,<-] (r1) -- ++(0,1);
%     \draw[very thick,red,->] (r2) -- ++(0,1);
%     \draw[very thick,red,->] (r3) -- ++(1,0);
%     \draw[very thick,red,<-] (r4) -- ++(1,0);
%     \draw[very thick,red,->] (r5) -- ++(1,0);;
%     \draw[very thick,red,<-] (r5) -- ++(0,1);
%     \draw[very thick,red,->] (r6) -- ++(-1,0);;
%     \draw[very thick,red,<-] (r6) -- ++(0,-1);
%
%     \draw[<-] (r1) ++(-0.1,0.5) -- ++(-0.5,0) node[left] {border 1,$y+1$,3,$c_1$};
%     \draw[<-] (r2) ++(0.1,0.5) -- ++(0.5,0) node[right] {border $n+1$,$y$,1,$c_2$};
%     \draw[<-] (r3) ++(0.5,-0.1) -- ++(0,-0.5) node[below] {border $x$,1,0,$c_3$};
%     \draw[<-] (r4) ++(0.5,0.1) -- ++(0,0.5) node[above] {border $x+1$,$n+1$,2,$c_4$};
%
%     \draw[<-] (r6) ++(0.1,-0.3) -- ++(2.2,1.3) node[above right] {border $x+1$,$y$,1,$c_5$};%
%     \draw[<-] (r5) ++(-0.1,0.5) -- ++(-3.2,1.3) node[above left] {border $x$,$y+1$,3,$c_5$};%
%     \draw[<-] (r5) ++(0.5,-0.1) -- ++(0,-0.5) node[below] {border $x$,$y$,0,$c_5$};
%     \draw[<-] (r6) ++(-0.5,0.1) -- ++(0,0.5) node[above] {border $x$,$y+1$,2,$c_5$};%
%     \fill
%     (r5) circle[radius=1.5pt] node[below left,xshift=1pt,yshift=1pt]
%     {\scriptsize$(x,y)$}
%     (r5-|r6) circle[radius=1.5pt] node[below right,xshift=-1pt,yshift=1pt]
%     {\scriptsize$(x+1,y)$}
%     (r5|-r6) circle[radius=1.5pt] node[above left,xshift=1pt,yshift=-1pt]
%     {\scriptsize$(x,y+1)$}
%     (r6) circle[radius=1.5pt] node[above right,xshift=-1pt,yshift=-1pt]
%     {\scriptsize$(x+1,y+1)$}
%     ;
%   \end{tikzpicture}
% \end{center}
%
% \nDescribeMacro{\qrtz_build_border_list:n}
% We build the list of borders with the function
% !\qrtz_build_border_list:n!, whose arg !#1! is the binary data.  It
% stores the borders in !\l_qrtz_border_seq! variable.  Each border is
% a comma list \vars{x},\vars{y},\vars{dir},\vars{component}, as
% described above.
%
% Loop for $x,y$ from 1 to $n$.  First !\int_step_inline:nn! for $x$,
% secont for $y$, so that $x = {}$!##1!, $y = {}$!####1!.
%    \begin{macrocode}
\cs_new:Nn \qrtz_build_border_list:n {
%    \end{macrocode}
% \par
% Next macro sets size and matrix from binary.
%    \begin{macrocode}
  \qrtz_compute_components:n { #1 }
  %
  \seq_clear:N \l_qrtz_border_seq
  %
  \int_step_inline:nn { \l_qrtz_size_int }
  {
    % x = ##1
    \int_step_inline:nn { \l_qrtz_size_int }
    {
      % y = ####1
%    \end{macrocode}
% Connected component number = !\l_qrtz_component!.
%    \begin{macrocode}
      \tl_set:Ne \l_qrtz_component { \qrtz_pixel:nn {##1}{####1} }
%    \end{macrocode}
% If pixel$(x,y)$ is black ($\text{component}>0$), check whether
% neighbor pixels are white.  We use explicitly the feature of
% !\bool_lazy_or:nnT! that the second test is done only if first is false.
%    \begin{macrocode}
      \int_compare:nNnT { \l_qrtz_component } > 0
      {
%    \end{macrocode}
% For left borders: add border $x$,$y+1$,3,\vars{component}
%    \begin{macrocode}
        \bool_lazy_or:nnT
        { \int_compare_p:nNn { ##1 } = 1 }
        { \int_compare_p:nNn { \qrtz_pixel:nn {##1 - 1}{####1} } = 0 }
        {
          \seq_put_left:Ne \l_qrtz_border_seq
          { ##1, \int_eval:n{ ####1 + 1 }, 3, \l_qrtz_component }
        }
        %
%    \end{macrocode}
% For right borders: add border $x+1$,$y$,1,\vars{component}
%    \begin{macrocode}
        \bool_lazy_or:nnT
        { \int_compare_p:nNn { ##1 } = { \l_qrtz_size_int } }
        { \int_compare_p:nNn { \qrtz_pixel:nn {##1 + 1}{####1} } = 0 }
        {
          \seq_put_left:Ne \l_qrtz_border_seq
          { \int_eval:n{ ##1 + 1 }, ####1, 1, \l_qrtz_component }
        }
        %
%    \end{macrocode}
% For top borders: add border $x+1$,$y+1$,2,\vars{component}
%    \begin{macrocode}
        \bool_lazy_or:nnT
        { \int_compare_p:nNn { ####1 } = { \l_qrtz_size_int } }
        { \int_compare_p:nNn { \qrtz_pixel:nn {##1}{####1+1} } = 0 }
        {
          \seq_put_left:Ne \l_qrtz_border_seq
          {\int_eval:n{##1+1}, \int_eval:n{####1+1}, 2, \l_qrtz_component }
        }
        %
%    \end{macrocode}
% For bottom borders: add border $x$,$y$,0,\vars{component}
%    \begin{macrocode}
        \bool_lazy_or:nnT
        { \int_compare_p:nNn { ####1 } = 1 }
        { \int_compare_p:nNn { \qrtz_pixel:nn {##1}{####1-1} } = 0 }
        {
          \seq_put_left:Ne \l_qrtz_border_seq
          { ##1, ####1, 0, \l_qrtz_component }
        }
      }
    }
  }
}
%    \end{macrocode}
%
% \subsection{Computation of the path}
% \label{sec:path}
%
% Now we get to the main task of the package.  Basicly, get a border, follow
% the path (always removing the “walked” borders) in the same
% connected component until get a closed path, output that subpath and
% repeat until list of borders is empty.
%
% The algorithm is the following:\medskip
%
% \noindent
% \textit{path} $\leftarrow$ “\,”\medskip
%
% \noindent
% \makebox[0pt][r]{\framebox{A}\quad}while \textit{border-list}\\
% \mbox{}~~\textit{can-cont} $\leftarrow$ true\\
% \mbox{}~~\textit{go-straight} $\leftarrow$ false \quad\textit{\color{gray!50!black}\% to force first output to path}\\
% \mbox{}~~get \textit{border} in \textit{border-list} \quad\textit{\color{gray!50!black}\% without removing it}\\
% \mbox{}~~set \textit{x},\textit{y},\textit{dir},\textit{component} from \textit{border}\medskip
%
% \noindent
% \makebox[0pt][r]{\framebox{B}\quad}\mbox{}~~while \textit{can-cont}\\
% \mbox{}~~~~remove \textit{border} \quad\textit{\color{gray!50!black}\% got at the beginning or tested in the if's at end of loop} \\
% \mbox{}~~~~if not \textit{go-straight}\quad\textit{\color{gray!50!black}\% at turn, output to path}\\
% \mbox{}~~~~~|~~\textit{path} $\leftarrow$ \textit{path} + “$(x,y)$-{}-”\\
% \mbox{}~~~~end-if\\
% \mbox{}~~~~set \textit{x},\textit{y} as the end point from \textit{border} \quad\textit{\color{gray!50!black}\% walk the border}\medskip
%
% \noindent
% \makebox[0pt][r]{\framebox{C}\quad}\mbox{}~~~~compute \textit{inner},\textit{outer},\textit{straight} borders\\
% \mbox{}~~~~\textit{\color{gray!50!black}\% inner = x,y,dir\emph{+}1,c,\quad straight = x,y,dir,c,\quad outer = x,y,dir–1,c,}\\
% \mbox{}~~~~if \textit{inner} in \textit{border-list}\\
% \mbox{}~~~~|~~\textit{go-straight} $\leftarrow$ false\\
% \mbox{}~~~~|~~\textit{border} $\leftarrow$ \textit{inner}\\
% \mbox{}~~~~else\\
% \mbox{}~~~~|~~if \textit{straight} in \textit{border-list}\\
% \mbox{}~~~~|~~|~~\textit{go-straight} $\leftarrow$ true\\
% \mbox{}~~~~|~~|~~\textit{border} $\leftarrow$ \textit{straight}\\
% \mbox{}~~~~|~~else\\
% \mbox{}~~~~|~~|~~if \textit{outer} in \textit{border-list}\\
% \mbox{}~~~~|~~|~~|~~\textit{go-straight} $\leftarrow$ false\\
% \mbox{}~~~~|~~|~~|~~\textit{border} $\leftarrow$ \textit{outer}\\
% \mbox{}~~~~|~~|~~else\\
% \mbox{}~~~~|~~|~~|~~\textit{can-cont} $\leftarrow$ false\quad\textit{\color{gray!50!black}\% dead end, restart process to new subpath}\\
% \mbox{}~~~~|~~|~~|~~\textit{path} $\leftarrow$ \textit{path} + “cycle”\\
% \mbox{}~~~~|~~|~~end-if\\
% \mbox{}~~~~|~~end-if\\
% \mbox{}~~~~end-if\\
% \mbox{}~~end-while\\
% end-while\bigskip
%
% \nDescribeMacro{\qrtz_build_tikz_path:nN}
% We implement the construction of the path in function
% !\qrtz_build_tikz_path:nN!. The args are !#1! = \vars{binary data}
% and !#2! = command that will hold the path.
%    \begin{macrocode}
\cs_new:Nn \qrtz_build_tikz_path:nN {
  \message{<Computing~ Tikz~ path~ ...}
  % build border list
  \qrtz_build_border_list:n { #1 }
%    \end{macrocode}
% Now the main action.
%
% Initializing !path!
%    \begin{macrocode}
  \tl_set:Nn \l_qrtz_path {}
%    \end{macrocode}
%  First loop at point \framebox{A}
%    \begin{macrocode}
  \bool_until_do:nn { \seq_if_empty_p:N \l_qrtz_border_seq }
  {
%    \end{macrocode}
% First code after \framebox{A}: initialize \textit{can-cont},
% \textit{go-straight}, get border and set \textit{x}, \textit{y},
% \textit{dir} and \textit{component} from it.  The value false to
% \textit{go-straight} forces first output to \textit{path} that must
% happen at beginning of new subpath.
%    \begin{macrocode}
    \bool_set_true:N \l_qrtz_can_continue_bool
    \bool_set_false:N \l_qrtz_continue_straight_bool
    \seq_get_left:NN \l_qrtz_border_seq \l_qrtz_border
    \tl_set:Ne \l_qrtz_x         { \clist_item:Nn \l_qrtz_border 1 }
    \tl_set:Ne \l_qrtz_y         { \clist_item:Nn \l_qrtz_border 2 }
    \tl_set:Ne \l_qrtz_dir       { \clist_item:Nn \l_qrtz_border 3 }
    \tl_set:Ne \l_qrtz_component { \clist_item:Nn \l_qrtz_border 4 }
%    \end{macrocode}
% Second loop at point \framebox{B}: looping through a full subpath,
% walking borders continuously until this is not possible in thhe same
% connected component.
%    \begin{macrocode}
    \bool_while_do:Nn \l_qrtz_can_continue_bool
    {
%    \end{macrocode}
% Processing the border: remove from list of borders, update path if
% there was a turn in direction, “walk” the border, that is, update
% $(x,y)$ as the end of that border.
%    \begin{macrocode}
      \seq_remove_all:NV \l_qrtz_border_seq \l_qrtz_border

      \bool_if:NF \l_qrtz_continue_straight_bool
      { % else
        \tl_put_right:Ne \l_qrtz_path { (\l_qrtz_x,\l_qrtz_y) -- }
      }

      \tl_set:Ne \l_qrtz_dir { \clist_item:Nn \l_qrtz_border 3 }

      \int_case:nn { \l_qrtz_dir }
      {
        0 { \tl_set:Ne \l_qrtz_x { \int_eval:n { \l_qrtz_x + 1 } } }
        1 { \tl_set:Ne \l_qrtz_y { \int_eval:n { \l_qrtz_y + 1 } } }
        2 { \tl_set:Ne \l_qrtz_x { \int_eval:n { \l_qrtz_x - 1 } } }
        3 { \tl_set:Ne \l_qrtz_y { \int_eval:n { \l_qrtz_y - 1 } } }
      }
%    \end{macrocode}
% Point \framebox{C}: compute all derivated borders that could
% continue the subpath: inner border has direction
% $\text{\textit{dir}}+1 \mod 4$, straight border has same
% \textit{dir} and outer has direction $\text{\textit{dir}}-1 \mod 4$.
%    \begin{macrocode}
      \tl_set:Ne \l_qrtz_inner { % inner=left: dir+1 mod 4
        \l_qrtz_x, \l_qrtz_y,
        \int_eval:n { \int_mod:nn { \l_qrtz_dir + 1 } { 4 } },
        \l_qrtz_component
      }

      \tl_set:Ne \l_qrtz_straight {
        \l_qrtz_x, \l_qrtz_y, \l_qrtz_dir, \l_qrtz_component
      }

      \tl_set:Ne \l_qrtz_outer { % outer=right: dir-1 +4 mod 4
        \l_qrtz_x, \l_qrtz_y,
        \int_eval:n { \int_mod:nn { \l_qrtz_dir + 3 } { 4 } },
        \l_qrtz_component
      }
%    \end{macrocode}
% Tests in block at point \framebox{C}: test if inner, straight or
% outer borders are in list of borders, setting \textit{go-straight}
% accordingly and setting \textit{border} as the found member.  his
% border set now will be processed in next iteration of the loop at
% \framebox{B}.
%    \begin{macrocode}
      \seq_if_in:NVTF \l_qrtz_border_seq \l_qrtz_inner
      {
        \bool_set_false:N \l_qrtz_continue_straight_bool
        \tl_set_eq:NN \l_qrtz_border \l_qrtz_inner
      }
      { % else
        \seq_if_in:NVTF \l_qrtz_border_seq \l_qrtz_straight
        {
          \bool_set_true:N \l_qrtz_continue_straight_bool
          \tl_set_eq:NN \l_qrtz_border \l_qrtz_straight
        }
        { % else
          \seq_if_in:NVTF \l_qrtz_border_seq \l_qrtz_outer
          {
            \bool_set_false:N \l_qrtz_continue_straight_bool
            \tl_set_eq:NN \l_qrtz_border \l_qrtz_outer
          }
          { % else (dead-end)
            \bool_set_false:N \l_qrtz_can_continue_bool
            \tl_put_right:Nn \l_qrtz_path { cycle }
          } % fi
        } % fi
      } % fi
    } % end-while
  } % end-while
%    \end{macrocode}
% At this point !\l_qrtz_path! holds the path of QRcode.  Set !#2! as it.
%    \begin{macrocode}
  \tl_set_eq:NN #2 \l_qrtz_path
  \message{~done>.^^J}%
}
%    \end{macrocode}
% \medskip
%
% Geneate variant \texttt{eN} to always expand binary data and make as
% non-expl alias of that.
%    \begin{macrocode}
\cs_generate_variant:Nn \qrtz_build_tikz_path:nN { eN }

\tl_set_eq:NN \QRTZBinaryToTikzPath \qrtz_build_tikz_path:eN
%    \end{macrocode}
%
% \subsection{Save paths in a \LaTeX3 prop list}
% \label{sec:prop}
%
% \DescribeMacro{\QRTZgetTikzPathMaybeSaved}
% The macro !\QRTZgetTikzPathMaybeSaved! is the main function to
% retrieve the path corresponding to a binary data.  If it was already
% computed in a previous run (either just compuuted or stored in the
% aux file) this path is stored into a \LaTeX3 property list
% (\textsf{l3prop} module) and retrieved by this function.  It is a
% variant of the function below.
%    \begin{macrocode}
\cs_new:Nn \qrtz_get_tikz_path_maybe_saved:nN {
  \prop_get:NeN \g_qrtz_paths_prop { #1 } { #2 }
%    \end{macrocode}
% \texttt{qrcode} oftion \texttt{forget} is respected.
%    \begin{macrocode}
  \use:c {ifqr@forget@mode} \tl_set_eq:NN #2 \q_no_value \fi
  \quark_if_no_value:NTF #2
  {
    \qrtz_build_tikz_path:nN { #1 }{ #2 }
    \qrtz_save_write_path_to_aux:ee { #1 }{ #2 }
  }
  {
    \message{<Using~ saved~ Tikz~ path>^^J}%
  }
}

\cs_generate_variant:Nn \qrtz_get_tikz_path_maybe_saved:nN { eN }

\tl_set_eq:NN \QRTZgetTikzPathMaybeSaved \qrtz_get_tikz_path_maybe_saved:eN
%    \end{macrocode}
%
% \subsection{Saving paths to aux file}
% \label{sec:aux}
%
% \DescribeMacro{\QRTZsavePath}
% The macro !\QRTZsavePath! \texttt{\{\vars{binary}\} \{\vars{tikz path}\}}
% associates key \vars{binary} to value \vars{tikz path}, for later
% use, to avoid recomputation of path and write correspondence to aux
% file.  It writes a fallback dummy definition of itself, in case this
% package is removed.  Its definition is actually a variant of the
% macro below.
%    \begin{macrocode}
\cs_new:Nn \qrtz_save_write_path_to_aux:nn {
  \bool_if:NF \g_qrtz_aux_fallback_written_bool
  {
    \iow_shipout:cn { @auxout } { \providecommand{\QRTZsavePath}[2]{} }
    \bool_gset_true:N \g_qrtz_aux_fallback_written_bool
  }
  \message{<Writing~ Tikz~ path~ to~ aux~ file>^^J}%
  \iow_shipout:cn { @auxout } { \QRTZsavePath {#1}{#2} }
%    \end{macrocode}
% Verifying if binary data was already saved; save if necessary.
%    \begin{macrocode}
\prop_get:NnN \g_qrtz_paths_prop { #1 } \l_tmpa_tl
  \quark_if_no_value:NT \l_tmpa_tl
  {
    \message{<Saving~ Tikz~ path~ to~ memory~ for~ later~ use>^^J}%
    \prop_gput:Nnn \g_qrtz_paths_prop { #1 } { #2 }
  }
}

\cs_generate_variant:Nn \qrtz_save_write_path_to_aux:nn { ee }

\tl_set_eq:NN \QRTZsavePath \qrtz_save_write_path_to_aux:nn
%    \end{macrocode}
%
% \subsection{Printing function for \texttt{qrcode} matrix and binary data}
% \label{sec:print}
%
% \nDescribeMacro{\QRTZprintQRmatrix} !\QRTZprintQRmatrix! is
% \texttt{qrcodetikz}'s counterpart of !\qr@printmatrix! from
% \texttt{qrcode}, that prints the QR code stored in a \texttt{qrcode}
% matrix.  In that package, matrices are stored with macros formed by
% the matrix name and matrix indexes.  Fortunately it has a function
% to convert these matrices to binary data, that we print with
% !\QRTZprintBinaryString!.
%
%    \begin{macrocode}
\cs_new:Nn \qrtz_print_qr_matrix:n {
  \message{^^J~(}
  \use:c{qr@matrixtobinary}{#1} % stores into \qr@binarymatrix@result
  \QRTZprintBinaryString{ \use:c{qr@binarymatrix@result} }
  \message{~)~}
}

\tl_set_eq:NN \QRTZprintQRmatrix \qrtz_print_qr_matrix:n
%    \end{macrocode}
%
% We will copy lots of chunks of !\qr@printsavedbinarymatrix! from
% \texttt{qrcode} package, so we decided to go in \LaTeXe{} mode, but
% missing \LaTeX3, specially by the trouble of the chain of
% !\expandafter! below.
%    \begin{macrocode}
\ExplSyntaxOff
%    \end{macrocode}
%
% \DescribeMacro{\qrcodeFillOptions}\DescribeMacro{\QRTZ@extraFillOpts}
% Macro that stores fill options and a macro that sets it.
%    \begin{macrocode}
\newcommand{\QRTZ@extraFillOpts}{}
\newcommand{\qrcodeFillOptions}[1]{\gdef\QRTZ@extraFillOpts{#1}}
%    \end{macrocode}
%
% \DescribeMacro{\QRTZprintBinaryString}

% Function !\QRTZprintBinaryString! is \texttt{qrcodetikz} counterpart
% of function !\qr@printsavedbinarymatrix!, the macro of
% \texttt{qrcode} that prints the QR code represented by a binary
% string.  We copy from it the computations and the use of !\parbox!,
% to ensure the same behavior of \texttt{qrcode} printing functions.
% It supposes context of a call of !\qrcode! command: !\qr@size! holds
% size, !\qr@desiredheight!, !\qr@modulesize!, !\qr@minipagewidth! are
% \TeX\ lengths and !\ifqr@tight! holds tight option.
%    \begin{macrocode}
\newcommand{\QRTZprintBinaryString}[1]{%
  \setlength{\qr@modulesize}{\qr@desiredheight}%
  \divide\qr@modulesize by \qr@size\relax
  \setlength{\qr@minipagewidth}{\qr@modulesize}%
  \multiply\qr@minipagewidth by \qr@size\relax
  \ifqr@tight
  \else
    \advance\qr@minipagewidth by 8\qr@modulesize
  \fi
%    \end{macrocode}
% After computations, we prepair the Ti\textit{k}Z settings: get the
% path for the binary data in !#1! \dots
%    \begin{macrocode}
  \QRTZgetTikzPathMaybeSaved{#1}{\QRTZtikzPath}%
%    \end{macrocode}
% and compute the scale. !\QRTZtikzPath! holds a path that displays
% data on a square of size $n ={}$!\qr@size!  cm that has to fit the
% length !\qr@desiredheight!. 1 in = 2.54 cm = 72.27 pt, so 1pt =
% 0.03514598 cm.  Doing the math, we have the scale below.
%    \begin{macrocode}
  \pgfmathsetmacro\QRTZtikzScale{0.03514598*\qr@desiredheight/\qr@size}%
%    \end{macrocode}
% We embed fill options in !\QRTZ@extraFillOpts! expanded once
% together with scale and even odd rule options.
%    \begin{macrocode}
  \expandafter\def\expandafter\QRTZinternalFillOptions\expandafter{\expandafter
    [\QRTZ@extraFillOpts,scale=\QRTZtikzScale,even odd rule]}%
%    \end{macrocode}
% Using the same !\parbox! as \texttt{qrcode} we fill the path.  With
% option \texttt{padding}, we enlarge the bounding box by 4 units: as
% the path contains data in the rectangle from $(1,1)$ to $(n+1,n+1)$,
% we add coordinates $(-3,-3)$ and $(n+5,n+5)$ to path, enlarging the
% bounding box inside Ti\textit{k}Z.
%    \begin{macrocode}
  \parbox{\qr@minipagewidth}{%
    \tikz
    \expandafter\fill\QRTZinternalFillOptions
    \ifqr@tight\else(-3,-3)(\qr@size+5,\qr@size+5)\fi
    \QRTZtikzPath ;%
  }%
}
%    \end{macrocode}
%
% \subsection{Replacing qrcode printing functions by new functions}
% \label{sec:on-off}
%
% To implement switches to turn on and off the replacements, we save
% copies of original functions and define macros that set original
% functions accordingly.
%    \begin{macrocode}
\let\qr@printmatrixORIGINAL\qr@printmatrix
\let\qr@printsavedbinarymatrixORIGINAL\qr@printsavedbinarymatrix

\newcommand{\qrcodetikzOn}{%
  \let\qr@printmatrix\QRTZprintQRmatrix
  \let\qr@printsavedbinarymatrix\QRTZprintBinaryString
}

\newcommand{\qrcodetikzOff}{%
  \let\qr@printmatrix\qr@printmatrixORIGINAL
  \let\qr@printsavedbinarymatrix\qr@printsavedbinarymatrixORIGINAL
}

\qrcodetikzOn
%    \end{macrocode}
%
% We silently fix a typo in \texttt{qrcode} (there,
% !\def\qr@fivezeros{11111}!), a not-so-serious bug, used only to compute
% a penalty).
%    \begin{macrocode}
\def\qr@fivezeros{00000}%
%    \end{macrocode}
%
% \Finale
%
\endinput
%
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
