From fbd4ce657997703fad5fba067ecb9acdfff252e3 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Wed, 12 Aug 2020 22:26:04 +0200 Subject: [PATCH] Feat: add qrcode support --- tools/examples/shortcuts_settings.pdf | Bin 123652 -> 124540 bytes tools/examples/shortcuts_settings.tex | 9 +- tools/style/myXsim.sty | 1 - tools/style/myhdr.sty | 5 - tools/style/qrcode.dtx | 3542 +++++++++++++++++++++++++ tools/style/qrcode.ins | 57 + tools/style/qrcode.sty | 3051 +++++++++++++++++++++ tools/style/shortcuts.sty | 8 +- 8 files changed, 6662 insertions(+), 11 deletions(-) create mode 100644 tools/style/qrcode.dtx create mode 100644 tools/style/qrcode.ins create mode 100644 tools/style/qrcode.sty diff --git a/tools/examples/shortcuts_settings.pdf b/tools/examples/shortcuts_settings.pdf index 4cdf0d1056f7687f71e215676724b9c25e64ab75..089606a95d2ff174150e06b5cf5a81bb0c5916c9 100644 GIT binary patch delta 38351 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 DZMisE delta 37476 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 Wyb%thAW=~%2~komE|{(=>Hh#a(88(! diff --git a/tools/examples/shortcuts_settings.tex b/tools/examples/shortcuts_settings.tex index 7cfeb0a..b3aa067 100644 --- a/tools/examples/shortcuts_settings.tex +++ b/tools/examples/shortcuts_settings.tex @@ -1,5 +1,6 @@ \documentclass[a4paper,10pt]{article} \usepackage{myXsim} +\usepackage{qrcode} \title{TITRE} \tribe{TRIBU} @@ -31,7 +32,7 @@ \item \verb+\vectCoord+ $\vectCoord{\#1}{\#2}$ \item \verb+\e+ $\e$ - \item \verb+\i+ $\i$ + % \item \verb+\i+ $\i$ \item \verb+\coefBino+ $\coefBino{\#1}{\#2}$ @@ -148,5 +149,11 @@ print("Le tarif est ", x*0.8) \end{lstlisting} +\section{QRcode} + +\verb+\usepackage{qrcode}+ + +\qrcode{phrase à coder} + \end{document} diff --git a/tools/style/myXsim.sty b/tools/style/myXsim.sty index a201e54..d9d9905 100644 --- a/tools/style/myXsim.sty +++ b/tools/style/myXsim.sty @@ -4,7 +4,6 @@ \RequirePackage{colorscheme} \RequirePackage{base} \RequirePackage{myhdr} -\RequirePackage{hyperref} \RequirePackage[no-files]{xsim} diff --git a/tools/style/myhdr.sty b/tools/style/myhdr.sty index fa74559..3cad0df 100644 --- a/tools/style/myhdr.sty +++ b/tools/style/myhdr.sty @@ -6,11 +6,6 @@ \RequirePackage{fancyhdr} -% Definition etc -\RequirePackage{amsthm} -\newtheorem*{definition}{Définition} -\newtheorem*{Remarque}{Remarque} - \newcommand{\op@entete}{} \newcommand{\op@typedoctmp}{} \newcommand{\op@tribe}{} diff --git a/tools/style/qrcode.dtx b/tools/style/qrcode.dtx new file mode 100644 index 0000000..02cf53a --- /dev/null +++ b/tools/style/qrcode.dtx @@ -0,0 +1,3542 @@ +% \iffalse meta-comment +% +% qrcode.ins +% Copyright 2014 by Anders O.F. Hendrickson (anders.hendrickson@snc.edu) +% +% 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 Anders O.F. Hendrickson. +% +% This work consists of the files qrcode.dtx and qrcode.ins +% and the derived file qrcode.sty. +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{qrcode.dtx} +% +%\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%\ProvidesPackage{qrcode} +%<*package> + [2015/01/08 v1.51 QR code generation] +% +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{hyperref} +\usepackage[nolinks]{qrcode} +\EnableCrossrefs +\CodelineIndex +\OnlyDescription +\RecordChanges +\begin{document} + \DocInput{qrcode.dtx} + \PrintChanges + %\PrintIndex +\end{document} +% +% \fi +% +% \CheckSum{0} +% +% \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 \~} +% +% +% \changes{v1.0}{2014/09/26}{Initial version} +% \changes{v1.5}{2015/01/08}{Added support for new lines and hyperlinks.} +% \changes{v1.51}{2015/01/14}{Bug fix.} +% +% \GetFileInfo{qrcode.sty} +% +% \DoNotIndex{\newcommand,\newenvironment,\def} +% +% \def\F{F} +% +% \title{The \textsf{qrcode} package: \\ +% \makebox[0pt][r]{\raisebox{-0.3\height}[0pt][0pt]{\qrcode[hyperlink,tight]{http://ctan.org/pkg/qrcode}}\rule{0.75in}{0pt}}Quick Response code \\ +% generation in \LaTeX\thanks{This document +% corresponds to \textsf{qrcode}~\fileversion, dated \filedate.}} +% \author{Anders Hendrickson\\ St.~Norbert College, De~Pere, WI, USA \\ \texttt{anders.hendrickson@snc.edu}} +% \date{January 8, 2015} +% +% \maketitle +% +% +% \section{Introduction} +% +% The proliferation of smartphones and tablets has led to the widespread +% use of Quick Response (QR) codes, which encode numeric, alphanumeric, kanji, +% or binary information into a square matrix of black and white pixels called modules. +% Although QR codes can encode any information up to almost three kilobytes, +% their most common use is as physical hyperlinks: a mobile device scans +% a printed QR code, decodes a URL, and automatically points a browser to that location. +% +% It is natural to want to include QR codes in certain \LaTeX\ documents; +% for example, one may want to direct the reader of a printed page to +% related interactive content online. +% Before now, the only \LaTeX\ package for producing QR codes was the +% immensely flexible {\tt pst-barcode}. As that package relies on +% {\tt pstricks}, however, it can be difficult to integrate with +% a pdf\LaTeX\ workflow,\footnote{% +% The {\tt auto-pst-pdf} or {\tt pstool} packages can make this possible +% by automatically running +% \LaTeX${}\rightarrow \tt dvips \rightarrow ps2pdf \rightarrow pdfcrop$ +% for each barcode generated in {\tt pstricks}, +% so long as the user is able and willing to enable {\tt\string\write18} +% in {\tt pdflatex} and install Perl. +% Judging by questions on {\tt tex.stackexchange.com} and {\tt latexcommunity.org}, +% this is a significant hurdle for some users. +% Moreover, according to {\tt http://tex.stackexchange.com/questions/72876/} +% this workflow may have trouble if the QR code is in a header.} +% and a pdf\LaTeX\ user may not want the extra overhead just to produce a QR code. +% If one wants to avoid {\tt pstricks}, a Lua\TeX\ solution was proposed at +% {\tt http://tex.stackexchange.com/questions/89649/}, +% and a plain\TeX\ solution can be found at +% {\catcode`\~=12\tt http://ktiml.mff.cuni.cz/~maj/QRcode.TeX}, +% but until now no \LaTeX\ package had been available that did not call on outside machinery. +% +% The {\tt qrcode} package, in contrast, implements the QR code algorithm using +% only \TeX\ and \LaTeX\ commands, so it should work with any \LaTeX\ workflow. +% Because it draws the squares constituting a QR code using the \TeX\ primitive +% |\rule|, there is no need to load any graphics package whatsoever. +% For a user who merely wants a QR code, this is the simplest solution. +% +% \section{Usage}\label{sect:usage} +% +% +% \DescribeMacro{\qrcode} +% The package provides just one command, |\qrcode|, with the following syntax: +% \begin{center} +% |\qrcode|\oarg{options}\marg{text to be encoded} +% \end{center} +% For example, |\qrcode[hyperlink,height=0.5in]{http://www.ctan.org}| produces +% \begin{center} +% \qrcode[hyperlink,height=0.5in]{http://www.ctan.org} +% \end{center} +% Although the most common use of QR codes is as URLs, +% the \meta{text to be encoded} can be almost any typed text. +% The few exceptions to this are described in section \ref{sect:specialcharacters}. +% +% \subsection{Package Options} +% +% \DescribeMacro{nolinks} +% When the |hyperref| package is loaded, +% by default |\qrcode| assumes its argument is a URL +% and makes the QR code produced a hyperlink to that URL. +% This default behavior may be changed by invoking the |nolinks| package option. +% For example, most of the QR codes in this document are not in fact URLs, +% so this documentation was typeset with |\usepackage[nolinks]{qrcode}|. +% The |hyperlinks| option is an antonym to |nolinks| and is the default. +% These options have no effect if hyperref is not loaded. +% +% \DescribeMacro{draft} +% \DescribeMacro{final} +% Creating QR codes for short URLs takes relatively little time.\footnote{On +% this author's laptop, even a 60-character URL (version 4, level M) adds +% only about 0.7 seconds of compilation time.} +% Because \TeX\ was designed for typesetting, not for extensive computations, +% however, if many small QR codes or a single large one are required, +% the time spent can be quite noticeable. To save compilation +% time while working on a large document, calling the |draft| option +% causes the package not to compute QR codes, but merely to insert placeholder +% symbols with no data. The |final| option is an antonym to |draft| +% and is the default. +% \begin{quote} +% \begin{tabular}{p{1.25in}p{3.5in}} +% {\qrcode[draft,version=15]{http://www.tug.org}} +% & +% \begin{minipage}{3in} +% \tt +% |\documentclass{article}| \\ +% |\usepackage[draft]{qrcode}| \\ +% |\begin{document}| \\ +% | \qrcode[version=15]{Dummy code}| \\ +% |\end{document}| +% \end{minipage} +% \end{tabular} +% \end{quote} +% The placeholder symbol produced in {\tt draft} mode will have the same size +% and dimensions as the actual QR code. +% +% To conserve processing time, when |\qrcode| computes the binary matrix representing +% a QR code, it saves that binary data as a string of 1's and 0's +% both in a macro and in the {\tt .aux} file. +% Thus if the same QR code is desired later in the document, or upon the next +% run of \LaTeX, the QR symbol can be redrawn immediately from the saved binary data. +% +% \DescribeMacro{forget} +% There may be times when this is not desired; testing of this package is the chief +% example, but one might also have reason to believe that the {\tt .aux} file +% contains bad data. +% Invoking the |forget| package option causes |\qrcode| to calculate +% every QR code anew, even if a QR code for that \meta{text to be encoded}, level, +% and version +% was read from the {\tt .aux} file or was already computed earlier in the document. +% +% \subsection{Options} +% \DescribeMacro{\qrset} +% Several options affect the appearance and encoding of the QR code; +% {\tt qrcode} uses the {\tt xkeyval} package to handle the setting +% and processing of key-value pairs. +% The following options may either be given as optional arguments +% to |\qrcode| or changed within a \TeX-grouping using the +% macro |\qrset|. +% \begin{quote} +% \begin{tabular}{p{6cm}p{2in}} +% \qrcode{ABCD} +% {\qrset{height=1cm}% +% \qrcode{EFGH}} +% \qrcode{IJKL} +% & +% \begin{minipage}{3in} +% |\qrcode{ABCD}| \\ +% |{\qrset{height=1cm}%| \\ +% | \qrcode{EFGH}}| \\ +% |\qrcode{IJKL}| +% \end{minipage} +% \end{tabular} +% \end{quote} +% +% \DescribeMacro{height} +% The |height=|\meta{dimen} key sets the printed height (and width) of the +% QR code. The default value is {\tt 2cm}. +% \begin{quote} +% \begin{tabular}{p{2in}p{2in}} +% \qrcode{ABCD} \qrcode[height=1cm]{ABCD} +% & |\qrcode{ABCD}| |\qrcode[height=1cm]{ABCD}| +% \end{tabular} +% \end{quote} +% +% \DescribeMacro{level} +% The QR code specification (ISO 18004:2006) includes four +% levels of encoding: Low, Medium, Quality, and High, in +% increasing order of error-correction capabaility. +% In general, for a given text a higher error-correction +% level requires more bits of information in the QR code. +% The key |level=|\meta{level specification} +% selects the minimum acceptable level. +% The \meta{level specification} may be |L|, |M|, |Q|, or |H|; +% the default is |M|. +% It may happen that the smallest QR code able to encode +% the specified text at the desired level +% is in fact large enough to provide a higher level of +% error-correction. If so, {\tt qrcode} automatically upgrades to the higher +% error-correction level, and a message is printed in the log file. +% +% \DescribeMacro{version} +% QR codes range in size from $21\times 21$ modules (``version 1'') +% to $177\times 177$ modules (``version 40''), in steps of 4 modules. +% The package automatically selects the smallest version large enough to encode +% the specified text at the desired error-correction level. +% Nevertheless, there might be occasions when a specific version is required; +% for example, perhaps a set of QR codes should have the same dimensions for +% aesthetic reasons, even though some encode shorter texts than others. +% For this reason, the key |version=|\meta{version specification} allows the user +% to specify a minimum version number, from 1 through 40, for the QR code. +% Setting |version=0| means ``as small as possible''; this is the default. +% If the desired version is not large enough to encode the text, the version +% will automatically be increased to accommodate the text, and a message will +% be placed in the log file. +% \begin{quote} +% \begin{tabular}{p{5.2cm}p{3in}} +% \raggedright +% \qrcode{ABCD} +% \qrcode[version=5]{ABCD} +% \medskip \\ +% \qrcode[version=10]{ABCD} +% \qrcode[version=20]{ABCD} +% & +% \begin{minipage}{3in} +% |\qrcode{ABCD}| \\ +% |\qrcode[version=5]{ABCD}| \\ +% |\medskip \\| \\ +% |\qrcode[version=10]{ABCD}| \\ +% |\qrcode[version=20]{ABCD}| +% \end{minipage} +% \end{tabular} +% \end{quote} +% +% +% \DescribeMacro{tight} +% \DescribeMacro{padding} +% The QR specification states that a QR code should be surrounded by white\-space +% of a width equal to that of four modules. In many applications, a document +% author is likely to provide sufficient spacing anyway (e.g., by placing the +% QR code in a {\tt center} environment, header, or |\marginpar|), so by +% default the |qrcode| package adds no spacing. If the option |padding| is +% specified, however, the QR code will automatically be surrounded with 4 modules' +% worth of white\-space. The key |tight| is an antonym of |padding|; the default is |tight|. +% +% \DescribeMacro{link} +% \DescribeMacro{nolink} +% \DescribeMacro{\qrcode*} +% As described above, if the |hyperref| package is loaded, +% then the QR codes produced in a PDF document can be made +% into hyperlinks to their text. The default behavior +% can be controlled with the options |nolinks| and |hyperlinks|, +% but this default can be overridden for individual QR codes by invoking +% the options |link| or |nolink|. +% Moreover, the starred version of the macro, |\qrcode*|, is a shorthand +% equivalent to |\qrcode[nolink]|. +% \begin{quote} +% \begin{tabular}{p{5.2cm}p{3in}} +% \raggedright +% \qrset{link, height=1.5cm} +% \qrcode{http://www.ctan.org} +% \qrcode[nolink]{This is not a URL.} +% \qrcode*{Neither is this.} +% & +% \begin{minipage}{3in} +% |\qrset{link, height=1.5cm}| \\ +% |\qrcode{http://www.ctan.org}| \\ +% |\qrcode[nolink]{This is not a URL.}| \\ +% |\qrcode*{Neither is this.}| +% \end{minipage} +% \end{tabular} +% \end{quote} +% +% \subsection{Special characters}\label{sect:specialcharacters} +% Many URLs can be processed by \TeX\ with no hiccups, +% but not infrequently a URL may contain the symbols |%|, |#|, +% |~|, |_|, and |&|. Moreover, QR codes need not just contain +% URL's, so a user may wish to encode text containing |^|, |$|, or spaces. +% The |qrcode| package offers two ways of coping with these special characters. +% +% First, the |\qrcode| command itself processes its \meta{text to be encoded} +% in a limited verbatim mode. The following characters will be encoded into +% the QR code as typed: +% \begin{center} +% |#| |$| |&| |^| |_| |~| |%| {\tt\char32} +% \end{center} +% and line breaks as well.\footnote{Technically, when the input character +% {\tt\char`\^\char`\^M} (CR, charcode 13) is encountered, +% the character {\tt\char`\^\char`\^J} (LF, charcode 10) is placed into the QR code.} +% Conspicuously absent from this list are |\|, |{|, and |}|. +% This is intentional, so that macros may be used within |\qrcode| +% to generate the \meta{text to be encoded} automatically. +% If these characters are desired, they may be obtained by ``escaping'' them +% with an extra backslash. +% \begin{quote} +% \begin{tabular}{p{2in}p{3in}} +% \qrset{height=1.5cm}% +% \qrcode{We can include #$&^_~%.} +% \def\foo{bar}% +% \qrcode{Set the \foo\ high.} +% \qrcode{We must escape \\emph\{this\}.} +% & \begin{minipage}{3in} +% |\qrset{height=1.5cm}%| \\ +% |\qrcode{We can include #$&^_~%.}| \\ +% |\def\foo{bar}%| \\ +% |\qrcode{Set the \foo\ high.}| \\ +% |\qrcode{We must escape \\emph\{this\}.}| +% \end{minipage} +% \end{tabular} +% \end{quote} +% +% As with all verbatim modes, however, because \TeX\ irrevocably sets catcodes +% when it first encounters characters, this will not work if the |\qrcode| macro +% is contained in another macro. If you call |\qrcode| inside an +% |\fbox| or a |\marginpar|, for example, and if your URL contains one of those +% special characters, you will either encounter error messages or (worse, because +% it is undetectable to the naked eye) have the wrong QR code typeset. +% In this scenario, you can still include any of the characters +% |#$&^_~%|{\tt\char32}|\{}| +% by escaping them with an extra backslash; +% so long as they eventually pass unexpanded to |\qrcode|, +% they will produce the correct QR code. +% A line break may be obtained with |\?|. +% \begin{quote} +% \begin{tabular}{p{1.5cm}p{2in}} +% \fbox{\qrcode[height=1cm]{\#\$\&\^\_\~\?\%\ \\\{\}}} +% & |\fbox{qrcode[height=1cm]{\#\$\&\^\_\~\?\%\ \\\{\}}}| +% \end{tabular} +% \end{quote} +% +% \section{Limitations and Cautions} +% +% \begin{itemize} +% \item The QR specification includes modes for encoding numeric, alphanumeric, +% or Kanji data more efficiently. This package does not (yet) offer +% those options. +% \item The QR specification offers ways to string lengthy data across multiple +% QR codes. This package does not implement that possibility. +% \end{itemize} +% +% \StopEventually{} +% +% \section{Implementation} +% \subsection{Key handling and options} +% \begin{macrocode} +%%PACKAGE LOADING +\RequirePackage{xcolor}% +\RequirePackage{xkeyval}% + +%%INITIAL CODE +\newif\ifqr@draft@mode +\newif\ifqr@forget@mode + +%%DECLARATION OF OPTIONS +\define@boolkey{qr}[qr@]{draft}[true]{\ifqr@draft\qr@draft@modetrue\else\qr@draft@modefalse\fi}% +\define@boolkey{qr}[qr@]{final}[true]{\ifqr@final\qr@draft@modefalse\else\qr@draft@modetrue\fi}% +\define@boolkey{qr}[qr@]{forget}[true]{\ifqr@forget\qr@forget@modetrue\else\qr@forget@modefalse\fi}% +\define@boolkey{qr}[qr@]{hyperlink}[true]{}% %This creates \ifqr@hyperlink. +\define@boolkey{qr}[qr@]{hyperlinks}[true]{\ifqr@hyperlinks\qr@hyperlinktrue\else\qr@hyperlinkfalse\fi}% +\define@boolkey{qr}[qr@]{link}[true]{\ifqr@link\qr@hyperlinktrue\else\qr@hyperlinkfalse\fi}% +\define@boolkey{qr}[qr@]{nolink}[true]{\ifqr@nolink\qr@hyperlinkfalse\else\qr@hyperlinktrue\fi}% %Make nolink an antonym. +\define@boolkey{qr}[qr@]{links}[true]{\ifqr@links\qr@hyperlinktrue\else\qr@hyperlinkfalse\fi}% +\define@boolkey{qr}[qr@]{nolinks}[true]{\ifqr@nolinks\qr@hyperlinkfalse\else\qr@hyperlinktrue\fi}% %Make nolinks an antonym. + +%%EXECUTION OF OPTIONS +\qr@draft@modefalse +\qr@forget@modefalse +\qr@hyperlinktrue + +\ProcessOptionsX + +% \end{macrocode} +% \subsection{Utilities} +% \begin{macrocode} +%COUNTERS +\newcounter{qr@i}% +\newcounter{qr@j}% +\newcount\qr@a +\newcount\qr@b +\newcount\qr@c + +%BASICS +\let\xa=\expandafter + +%This is for messages. +\newlinechar=`\^^J + + +%Tests +\def\qr@relax{\relax}% + +%Manipulating macros +\def\qr@preface@macro#1#2{% + % #1 = macro name + % #2 = text to add to front of macro + \def\qr@tempb{#2}% + \xa\xa\xa\def\xa\xa\xa#1\xa\xa\xa{\xa\qr@tempb #1}% +}% + +\def\qr@g@preface@macro#1#2{% + % #1 = macro to be appended to + % #2 = code to add + \edef\qr@tempb{#2}% + \xa\xa\xa\gdef\xa\xa\xa#1\xa\xa\xa{\xa\qr@tempb#1}% +} + + +\def\qr@getstringlength#1{% + \bgroup + \qr@a=0% + \xdef\qr@thestring{#1}% + \xa\qr@stringlength@recursive\xa(\qr@thestring\relax\relax)% + \xdef\qr@stringlength{\the\qr@a}% + \egroup +}% + +\def\qr@stringlength@recursive(#1#2){% + \def\qr@testi{#1}% + \ifx\qr@testi\qr@relax + %we are done. + \let\qr@next=\relax% + \else + \advance\qr@a by 1% + \def\qr@next{\qr@stringlength@recursive(#2)}% + \fi + \qr@next +}% +% \end{macrocode} +% \subsubsection{For-loop macro} +% We implement a macro |\qr@for| with the syntax +% \begin{center} +% |\qr@for| \meta{control sequence}=\meta{number} to \meta{number} by \meta{number} \marg{loop body} +% \end{center} +% The \meta{control sequence} becomes the loop variable, +% which is a \TeX\ counter. +% For example, |\qr@for \i=1 to 8 by 2 {\fbox{\number\i}}| +% produces {\makeatletter\qr@for \i=1 to 8 by 2 {\fbox{\number\i}}}. +% \begin{macrocode} +%The \qr@for@depth counter measures the depth of our loop. +%The outermost loop has depth zero. +\newcount\qr@for@depth% +\newcount\qr@for@maxdepth% +\qr@for@depth=0% +\qr@for@maxdepth=0% +%These counters are used in the qr@for loop. +\newcount\qr@for@start% +\newcount\qr@for@end% +\newcount\qr@for@step% +%Now a macro to get a new count for every depth as needed. +\def\qr@allocate@new@for@counter{% + \global\advance\qr@for@maxdepth by 1% + \newcount\qr@newforcount% + \xa\global\xa\let\csname qr@for@var@\the\qr@for@maxdepth\endcsname=\qr@newforcount% +}% + +\newif\ifqr@loopshouldrun +%The extra # in the following definition makes sure #4 scoops up everything up to the next opening brace. +%This is needed so the step can include more than one character without being enclosed in braces itself. +\def\qr@for #1=#2to#3by#4#{% + \qr@for@int{#1}{#2}{#3}{#4}% +}% +\long\def\qr@for@int#1#2#3#4#5{% + \bgroup + %Because we're working within a TeX group, + %any values of \qr@for@start, \qr@for@end, and \qr@for@step from an outer loop + %will be restored after the \egroup. + % + %For the \qr@for@var itself, however, we need a different counter, + %because the user's text within the loop might need to access the variable from the outer loop. + \advance\qr@for@depth by 1\relax% This is a local change. + \ifnum\qr@for@depth>\qr@for@maxdepth% + %This is the first time we have gone to this depth of nesting! + %We should only be over by one. + \qr@allocate@new@for@counter% + \fi +% \showthe\qr@for@depth% + \xa\let\xa\qr@for@var\xa=\csname qr@for@var@\the\qr@for@depth\endcsname% + %Now \qr@for@var points to the same register as \qr@for@var@3 or something. + %The next line lets the user-level variable (e.g., \i or \j) point to the same count register. + \let#1=\qr@for@var% + %Now establish the looping parameters. + \edef\qr@for@start@text{#2}% + \edef\qr@for@end@text{#3}% + \edef\qr@for@step@text{#4}% + \def\qr@for@body{\bgroup #5\egroup}% + \xa\qr@for@start\qr@for@start@text\relax% + \xa\qr@for@end \qr@for@end@text\relax% + \xa\qr@for@step \qr@for@step@text\relax% + % + %Next, test whether the loop should run at all. + % * "\qr@for \i = 1 to 0 by 1" should fail. + % * "\qr@for \i = 3 to 5 by -1" should fail. + % * "\qr@for \i = 6 to 2 by 1" should fail. + % * "\qr@for \i = 4 to 4 by -1" should run. + % * "\qr@for \i = 4 to 4 by 1" should run. + % * "\qr@for \i = 5 to 7 by 0" should fail. + %The loop should fail if (step)=0 or if (step) and (end-start) have opposite signs. + %The loop will fail if (step=0) or (step)*(end-start)<0. + % TODO: "\qr@for \i = 5 to 5 by 0" should run (just one iteration). + \qr@loopshouldruntrue + \ifnum\qr@for@step=0\relax + \qr@loopshouldrunfalse + \fi + \qr@a=\qr@for@end% + \advance\qr@a by -\qr@for@start% + \multiply\qr@a by \qr@for@step% + \ifnum\qr@a<0\relax + \qr@loopshouldrunfalse + \fi + \ifqr@loopshouldrun + \qr@for@var=\qr@for@start% + \ifnum\qr@for@step>0\relax + \def\qr@for@recursive{% + \qr@for@body% + \advance\qr@for@var by \qr@for@step% + \ifnum\qr@for@var>\qr@for@end% + \let\qr@for@next=\relax% + \else% + \let\qr@for@next=\qr@for@recursive% + \fi% + \qr@for@next% + }% + \else + \def\qr@for@recursive{% + \qr@for@body% + \advance\qr@for@var by \qr@for@step% + \ifnum\qr@for@var<\qr@for@end% + \let\qr@for@next=\relax% + \else% + \let\qr@for@next=\qr@for@recursive% + \fi% + \qr@for@next% + }% + \fi + \qr@for@recursive% + \fi + \egroup +}% +% \end{macrocode} +% \subsubsection{Base conversions} +% \begin{macrocode} +\def\qr@padatfront#1#2{% + % #1 = macro containing text to pad + % #2 = desired number of characters + % Pads a number with initial zeros. + \qr@getstringlength{#1}% + \qr@a=\qr@stringlength\relax% + \advance\qr@a by 1\relax% + \qr@for \i = \qr@a to #2 by 1\relax% + {\qr@g@preface@macro{#1}{0}}% +} + + +\qr@a=-1\relax% +\def\qr@savehexsymbols(#1#2){% + \advance\qr@a by 1\relax% + \xa\def\csname qr@hexchar@\the\qr@a\endcsname{#1}% + \xa\edef\csname qr@hextodecimal@#1\endcsname{\the\qr@a}% + \ifnum\qr@a=15\relax + %Done. + \let\qr@next=\relax% + \else + \def\qr@next{\qr@savehexsymbols(#2)}% + \fi% + \qr@next% +}% +\qr@savehexsymbols(0123456789abcdef\relax\relax)% + + +\def\qr@decimaltobase#1#2#3{% + % #1 = macro to store result + % #2 = decimal representation of a positive integer + % #3 = new base + \bgroup + \edef\qr@newbase{#3}% + \gdef\qr@base@result{}% + \qr@a=#2\relax% + \qr@decimaltobase@recursive% + \xdef#1{\qr@base@result}% + \egroup +} +\def\qr@decimaltobase@recursive{% + \qr@b=\qr@a% + \divide\qr@b by \qr@newbase\relax + \multiply\qr@b by -\qr@newbase\relax + \advance\qr@b by \qr@a\relax% + \divide\qr@a by \qr@newbase\relax% + \ifnum\qr@b<10\relax + \edef\qr@newdigit{\the\qr@b}% + \else + \edef\qr@newdigit{\csname qr@hexchar@\the\qr@b\endcsname}% + \fi + \edef\qr@argument{{\noexpand\qr@base@result}{\qr@newdigit}}% + \xa\qr@g@preface@macro\qr@argument% + \ifnum\qr@a=0\relax + \relax + \else + \xa\qr@decimaltobase@recursive + \fi +} + +\newcommand\qr@decimaltohex[3][0]{% + % #1 (opt.) = number of hex digits to create + % #2 = macro to store result + % #3 = decimal digits to convert + \qr@decimaltobase{#2}{#3}{16}% + \qr@padatfront{#2}{#1}% +} + + +\newcommand\qr@decimaltobinary[3][0]{% + % #1 (opt.) = number of bits to create + % #2 = macro to store result + % #3 = decimal digits to convert + \qr@decimaltobase{#2}{#3}{2}% + \qr@padatfront{#2}{#1}% +} + +\qr@for \i = 0 to 15 by 1% + {% + \qr@decimaltohex[1]{\qr@hexchar}{\the\i}% + \qr@decimaltobinary[4]{\qr@bits}{\the\i}% + \xa\xdef\csname qr@b2h@\qr@bits\endcsname{\qr@hexchar}% + \xa\xdef\csname qr@h2b@\qr@hexchar\endcsname{\qr@bits}% + }% + + + +\newcommand\qr@binarytohex[3][\relax]{% + % #1 (optional) = # digits desired + % #2 = macro to save to + % #3 = binary string (must be multiple of 4 bits) + \def\qr@test@i{#1}% + \ifx\qr@test@i\qr@relax% + %No argument specified + \def\qr@desireddigits{0}% + \else + \def\qr@desireddigits{#1}% + \fi + \gdef\qr@base@result{}% + \edef\qr@argument{(#3\relax\relax\relax\relax\relax)}% + \xa\qr@binarytohex@int\qr@argument% + \qr@padatfront{\qr@base@result}{\qr@desireddigits}% + \xdef#2{\qr@base@result}% +} +\def\qr@binarytohex@int(#1#2#3#4#5){% + % #1#2#3#4 = 4 bits + % #5 = remainder, including \relax\relax\relax\relax\relax terminator + \def\qr@test@i{#1}% + \ifx\qr@test@i\qr@relax% + %Done. + \def\qr@next{\relax}% + \else% + \xdef\qr@base@result{\qr@base@result\csname qr@b2h@#1#2#3#4\endcsname}% + \def\qr@next{\qr@binarytohex@int(#5)}% + \fi% + \qr@next% +} + +\newcommand\qr@hextobinary[3][\relax]{% + % #1 (optional) = # bits desired + % #2 = macro to save to + % #3 = hexadecimal string + \bgroup + \def\qr@test@i{#1}% + \ifx\qr@test@i\qr@relax% + %No argument specified + \def\qr@desireddigits{0}% + \else + \def\qr@desireddigits{#1}% + \fi + \gdef\qr@base@result{}% + \edef\qr@argument{(#3\relax\relax)}% + \xa\qr@hextobinary@int\qr@argument% + \qr@padatfront{\qr@base@result}{\qr@desireddigits}% + \xdef#2{\qr@base@result}% + \egroup +} +\def\qr@hextobinary@int(#1#2){% + % #1 = hexadecimal character + % #2 = remainder, including \relax\relax terminator + \def\qr@test@@i{#1}% + \ifx\qr@test@@i\qr@relax% + %Done. + \def\qr@next{\relax}% + \else% + \xdef\qr@base@result{\qr@base@result\csname qr@h2b@#1\endcsname}% + \def\qr@next{\qr@hextobinary@int(#2)}% + \fi% + \qr@next% +} + +\def\qr@hextodecimal#1#2{% + \edef\qr@argument{#2}% + \xa\qr@a\xa=\xa\number\xa"\qr@argument\relax% + \edef#1{\the\qr@a}% +} + +\def\qr@hextodecimal#1#2{% + % #1 = macro to store result + % #2 = hexadecimal representation of a positive integer + \bgroup + \qr@a=0\relax% + \edef\qr@argument{(#2\relax)}% + \xa\qr@hextodecimal@recursive\qr@argument% + \xdef#1{\the\qr@a}% + \egroup +} +\def\qr@hextodecimal@recursive(#1#2){% + % #1 = first hex char + % #2 = remainder + \advance \qr@a by \csname qr@hextodecimal@#1\endcsname\relax% + \edef\qr@testii{#2}% + \ifx\qr@testii\qr@relax% + %Done. + \let\qr@next=\relax% + \else + %There's at least one more digit. + \multiply\qr@a by 16\relax + \edef\qr@next{\noexpand\qr@hextodecimal@recursive(#2)}% + \fi% + \qr@next% +} +% \end{macrocode} +% \subsubsection{Catcode setup} +% \begin{macrocode} +%The following catcode trickery creates special characters +%with catcode 12 (other) for use in our verbatim handling. +{\catcode`\ =12\relax\gdef\qr@otherspace{ }}% +{\catcode`\%=12\relax\gdef\qr@otherpercent{%}}% +{\catcode`\#=12\relax\gdef\qr@otherpound{#}}% +{\catcode`\|=0\relax|catcode`|\=12|relax|gdef|qr@otherbackslash{\}}% +{\catcode`\^^J=12\relax\gdef\qr@otherlf{^^J}}% +\bgroup + \catcode`\<=1\relax + \catcode`\>=2\relax + \catcode`\{=12\relax\gdef\qr@otherleftbrace<{>% + \catcode`\}=12\relax\gdef\qr@otherrightbrace<}>% +\egroup% +{\catcode`\&=12\relax\gdef\qr@otherampersand{&}}% +{\catcode`\~=12\relax\gdef\qr@othertilde{~}}% +{\catcode`\^=12\relax\gdef\qr@othercaret{^}}% +{\catcode`\_=12\relax\gdef\qr@otherunderscore{_}}% +{\catcode`\$=12\relax\gdef\qr@otherdollar{$}}% + +%Line feeds require some special handling. \TeX\ reads a line feed in the input +%as |^^M| (carriage return, character code 13), but it should be encoded in a +%QR code as |^^J| (line feed, character code 10). +%To do this, we make |^^M| an active character and a synonym for a |^^J| with catcode 12. +%Note that the macro |\qr@verbatimlinefeeds| must itself be processed with |^^M| active. +{\catcode`\^^M=13\relax\gdef\qr@verbatimlinefeeds{\let^^M=\qr@otherlf}} +\def\qr@verbatimcatcodes{% + \catcode`\#=12\relax + \catcode`\$=12\relax + \catcode`\&=12\relax + \catcode`\^=12\relax + \catcode`\_=12\relax + \catcode`\~=12\relax + \catcode`\%=12\relax + \catcode`\ =12\relax + \catcode`\^^M=13\relax\qr@verbatimlinefeeds}% + +\def\qr@setescapedspecials{% + \let\ =\qr@otherspace% + \let\%=\qr@otherpercent% + \let\#=\qr@otherpound% + \let\&=\qr@otherampersand% + \let\^=\qr@othercaret% + \let\_=\qr@otherunderscore% + \let\~=\qr@othertilde% + \let\$=\qr@otherdollar% + \let\\=\qr@otherbackslash% + \let\{=\qr@otherleftbrace% + \let\}=\qr@otherrightbrace% + \let\?=\qr@otherlf% +}% +% \end{macrocode} +% \subsection{Plotting} +% \begin{macrocode} +\def\qr@creatematrix#1{% + \xa\gdef\csname #1\endcsname##1##2{% + \csname #1@##1@##2\endcsname + }% +}% + + +\def\qr@storetomatrix#1#2#3#4{% + % #1 = matrix name + % #2 = row number + % #3 = column number + % #4 = value of matrix entry + \xa\gdef\csname #1@#2@#3\endcsname{#4}% +}% + +\def\qr@estoretomatrix#1#2#3#4{% + % This version performs exactly one expansion on #4. + % #1 = matrix name + % #2 = row number + % #3 = column number + % #4 = value of matrix + \xa\xa\xa\gdef\xa\xa\csname #1@#2@#3\endcsname\xa{#4}% +}% + +\def\qr@matrixentry#1#2#3{% + % #1 = matrix name + % #2 = row number + % #3 = column number + \csname #1@#2@#3\endcsname% +}% + + + +\def\qr@createsquareblankmatrix#1#2{% + \qr@creatematrix{#1}% + \xa\gdef\csname #1@numrows\endcsname{#2}% + \xa\gdef\csname #1@numcols\endcsname{#2}% + \qr@for \i = 1 to #2 by 1% + {\qr@for \j = 1 to #2 by 1% + {\qr@storetomatrix{#1}{\the\i}{\the\j}{\qr@blank}}}% +}% + +\def\qr@numberofrowsinmatrix#1{% + \csname #1@numrows\endcsname% +}% + +\def\qr@numberofcolsinmatrix#1{% + \csname #1@numcols\endcsname% +}% + +\def\qr@setnumberofrows#1#2{% + \xa\xdef\csname #1@numrows\endcsname{#2}% +}% + +\def\qr@setnumberofcols#1#2{% + \xa\xdef\csname #1@numcols\endcsname{#2}% +}% + +\newlength\qr@desiredheight +\setlength\qr@desiredheight{2cm}% +\newlength\qr@modulesize +\newlength\qr@minipagewidth + +\def\qr@printmatrix#1{% + \def\qr@black{\rule{\qr@modulesize}{\qr@modulesize}}% + \def\qr@white{\rule{\qr@modulesize}{0pt}}% + \def\qr@black@fixed{\rule{\qr@modulesize}{\qr@modulesize}}% + \def\qr@white@fixed{\rule{\qr@modulesize}{0pt}}% + \def\qr@black@format{\rule{\qr@modulesize}{\qr@modulesize}}% + \def\qr@white@format{\rule{\qr@modulesize}{0pt}}% + %Set module size + \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 + \begin{minipage}{\qr@minipagewidth}% + \baselineskip=\qr@modulesize% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% %Blank space at top. + \qr@for \i = 1 to \qr@numberofrowsinmatrix{#1} by 1% + {\ifqr@tight\else\rule{4\qr@modulesize}{0pt}\fi% %Blank space at left. + \qr@for \j = 1 to \qr@numberofcolsinmatrix{#1} by 1% + {\qr@matrixentry{#1}{\the\i}{\the\j}}% + \par}% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% + \end{minipage}% +}% + +\def\qr@printsavedbinarymatrix#1{% + \edef\qr@binarystring{#1\relax\relax}% + %Set module size + \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 + \begin{minipage}{\qr@minipagewidth}% + \baselineskip=\qr@modulesize% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% %Blank space at top. + \qr@for \i = 1 to \qr@size by 1% + {\ifqr@tight\else\rule{4\qr@modulesize}{0pt}\fi% %Blank space at left. + \qr@for \j = 1 to \qr@size by 1% + {\edef\qr@theargument{(\qr@binarystring)}% + \xa\qr@printsavedbinarymatrix@int\qr@theargument + }% + \par}% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% + \end{minipage}% +}% + +\def\qr@printsavedbinarymatrix@int(#1#2){% + % #1 = first bit, either 1 or 0. + % #2 = remainder of string, terminating with \relax\relax + % There's no need to check for EOF here, because + % we'll only call this n^2 times. + \ifcase #1\relax + \rule{\qr@modulesize}{0pt}% % 0: white square + \or + \rule{\qr@modulesize}{\qr@modulesize}% % 1: black square + \fi + \xdef\qr@binarystring{#2}% +}% + +\def\qr@createliteralmatrix#1#2#3{% + % #1 = matrix name + % #2 = m, the number of rows and columns in the square matrix + % #3 = a string of m^2 tokens to be written into the matrix + \qr@creatematrix{#1}% + \xa\xdef\csname #1@numrows\endcsname{#2}% + \xa\xdef\csname #1@numcols\endcsname{#2}% + \gdef\qr@literalmatrix@tokens{#3}% + \qr@for \i = 1 to #2 by 1% + {\qr@for \j = 1 to #2 by 1% + {\xa\qr@createliteralmatrix@int\xa(\qr@literalmatrix@tokens)% + \qr@estoretomatrix{#1}{\the\i}{\the\j}{\qr@entrytext}% + }% + }% +} +\def\qr@createliteralmatrix@int(#1#2){% + \def\qr@entrytext{#1}% + \gdef\qr@literalmatrix@tokens{#2}% +} + + +\qr@createliteralmatrix{finderpattern}{8}{% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed% + \qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed% +}% + +\qr@createliteralmatrix{alignmentpattern}{5}{% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed% +}% + + + + +\def\qr@copymatrixentry#1#2#3#4#5#6{% + % Copy the (#2,#3) entry of matrix #1 + % to the (#5,#6) position of matrix #4. + \xa\xa\xa\global% + \xa\xa\xa\let\xa\xa\csname #4@#5@#6\endcsname% + \csname #1@#2@#3\endcsname% +}% + +\def\qr@createduplicatematrix#1#2{% + % #1 = name of copy + % #2 = original matrix to be copied + \qr@creatematrix{#1}% + \qr@for \i = 1 to \qr@numberofrowsinmatrix{#2} by 1% + {\qr@for \j = 1 to \qr@numberofcolsinmatrix{#2} by 1% + {\qr@copymatrixentry{#2}{\the\i}{\the\j}{#1}{\the\i}{\the\j}% + }% + }% + \qr@setnumberofrows{#1}{\qr@numberofrowsinmatrix{#2}}% + \qr@setnumberofcols{#1}{\qr@numberofcolsinmatrix{#2}}% +}% + +\def\qr@placefinderpattern@int#1#2#3#4#5{% + % Work on matrix #1. + % Start in position (#2, #3) -- should be a corner + % #4 indicates horizontal direction (1=right, -1=left) + % #5 indicates vertical direction (1=down, -1=up) + % + % In this code, \sourcei and \sourcej are TeX counts working through the finderpattern matrix, + % and i and j are LaTeX counters indicating positions in the big matrix. + \setcounter{qr@i}{#2}% + \qr@for \sourcei=1 to 8 by 1% + {\setcounter{qr@j}{#3}% + \qr@for \sourcej=1 to 8 by 1% + {\qr@copymatrixentry{finderpattern}{\the\sourcei}{\the\sourcej}% + {#1}{\theqr@i}{\theqr@j}% + \addtocounter{qr@j}{#5}% + }% + \addtocounter{qr@i}{#4}% + }% +}% + +\def\qr@placefinderpatterns#1{% + % #1=matrix name + \qr@placefinderpattern@int{#1}{1}{1}{1}{1}% + \qr@placefinderpattern@int{#1}{\qr@numberofrowsinmatrix{#1}}{1}{-1}{1}% + \qr@placefinderpattern@int{#1}{1}{\qr@numberofcolsinmatrix{#1}}{1}{-1}% +}% + +\def\qr@placetimingpatterns#1{% + %Set \qr@endingcol to n-8. + \qr@a=\qr@size\relax% + \advance\qr@a by -8\relax% + \edef\qr@endingcol{\the\qr@a}% + \qr@for \j = 9 to \qr@endingcol by 1% + {\ifodd\j\relax% + \qr@storetomatrix{#1}{7}{\the\j}{\qr@black@fixed}% + \qr@storetomatrix{#1}{\the\j}{7}{\qr@black@fixed}% + \else% + \qr@storetomatrix{#1}{7}{\the\j}{\qr@white@fixed}% + \qr@storetomatrix{#1}{\the\j}{7}{\qr@white@fixed}% + \fi% + }% +}% + +\def\qr@placealignmentpattern@int#1#2#3{% + % Work on matrix #1. + % Write an alignment pattern into the matrix, centered on (#2,#3). + \qr@a=#2\relax% + \advance\qr@a by -2\relax% + \qr@b=#3\relax% + \advance\qr@b by -2\relax% + \setcounter{qr@i}{\the\qr@a}% + \qr@for \i=1 to 5 by 1% + {\setcounter{qr@j}{\the\qr@b}% + \qr@for \j=1 to 5 by 1% + {\qr@copymatrixentry{alignmentpattern}{\the\i}{\the\j}% + {#1}{\theqr@i}{\theqr@j}% + \stepcounter{qr@j}% + }% + \stepcounter{qr@i}% + }% +}% + +\newif\ifqr@incorner% +\def\qr@placealignmentpatterns#1{% + %There are k^2-3 alignment patterns, + %arranged in a (k x k) grid within the matrix. + %They begin in row 7, column 7, + %except that the ones in the NW, NE, and SW corners + %are omitted because of the finder patterns. + %Recall that + % * \qr@k stores k, + % * \qr@alignment@firstskip stores how far between the 1st and 2nd row/col, & + % * \qr@alignment@generalskip stores how far between each subsequent row/col. + \xa\ifnum\qr@k>0\relax + %There will be at least one alignment pattern. + %N.B. k cannot equal 1. + \xa\ifnum\qr@k=2\relax + % 2*2-3 = exactly 1 alignment pattern. + \qr@a=7\relax + \advance\qr@a by \qr@alignment@firstskip\relax + \xdef\qr@target@ii{\the\qr@a}% + \qr@placealignmentpattern@int{#1}{\qr@target@ii}{\qr@target@ii}% + \else + % k is at least 3, so the following loops should be safe. + \xdef\qr@target@ii{7}% + \qr@for \ii = 1 to \qr@k by 1% + {\ifcase\ii\relax% + \relax% \ii should never equal 0. + \or + \xdef\qr@target@ii{7}% If \ii = 1, we start in row 7. + \or + %If \ii = 2, we add the firstskip. + \qr@a=\qr@target@ii\relax% + \advance\qr@a by \qr@alignment@firstskip\relax% + \xdef\qr@target@ii{\the\qr@a}% + \else + %If \ii>2, we add the generalskip. + \qr@a=\qr@target@ii\relax% + \advance\qr@a by \qr@alignment@generalskip\relax% + \xdef\qr@target@ii{\the\qr@a}% + \fi + \qr@for \jj = 1 to \qr@k by 1% + {\ifcase\jj\relax% + \relax% \jj should never equal 0. + \or + \xdef\qr@target@jj{7}% If \jj=1, we start in row 7. + \or + %If \jj=2, we add the firstskip. + \qr@a=\qr@target@jj\relax% + \advance\qr@a by \qr@alignment@firstskip% + \xdef\qr@target@jj{\the\qr@a}% + \else + %If \jj>2, we add the generalskip. + \qr@a=\qr@target@jj\relax% + \advance\qr@a by \qr@alignment@generalskip% + \xdef\qr@target@jj{\the\qr@a}% + \fi + \qr@incornerfalse% + \ifnum\ii=1\relax + \ifnum\jj=1\relax + \qr@incornertrue + \else + \ifnum\qr@k=\jj\relax + \qr@incornertrue + \fi + \fi + \else + \xa\ifnum\qr@k=\ii\relax + \ifnum\jj=1\relax + \qr@incornertrue + \fi + \fi + \fi + \ifqr@incorner + \relax + \else + \qr@placealignmentpattern@int{#1}{\qr@target@ii}{\qr@target@jj}% + \fi + }% ends \qr@for \jj + }% ends \qr@for \ii + \fi + \fi +}% + +\def\qr@placedummyformatpatterns#1{% + \qr@for \j = 1 to 9 by 1% + {\ifnum\j=7\relax% + \else% + \qr@storetomatrix{#1}{9}{\the\j}{\qr@format@square}% + \qr@storetomatrix{#1}{\the\j}{9}{\qr@format@square}% + \fi% + }% + \setcounter{qr@j}{\qr@size}% + \qr@for \j = 1 to 8 by 1% + {\qr@storetomatrix{#1}{9}{\theqr@j}{\qr@format@square}% + \qr@storetomatrix{#1}{\theqr@j}{9}{\qr@format@square}% + \addtocounter{qr@j}{-1}% + }% + %Now go back and change the \qr@format@square in (n-8,9) to \qr@black@fixed. + \addtocounter{qr@j}{1}% + \qr@storetomatrix{#1}{\theqr@j}{9}{\qr@black@fixed}% +}% + +\def\qr@placedummyversionpatterns#1{% + \xa\ifnum\qr@version>6\relax + %Must include version information. + \global\c@qr@i=\qr@size% + \global\advance\c@qr@i by -10\relax% + \qr@for \i = 1 to 3 by 1% + {\qr@for \j = 1 to 6 by 1% + {\qr@storetomatrix{#1}{\theqr@i}{\the\j}{\qr@format@square}% + \qr@storetomatrix{#1}{\the\j}{\theqr@i}{\qr@format@square}% + }% + \stepcounter{qr@i}% + }% + \fi +}% + +\def\qr@writebit(#1#2)#3{% + % #3 = matrix name + % (qr@i,qr@j) = position to write in (LaTeX counters) + % #1 = bit to be written + % #2 = remaining bits plus '\relax' as an end-of-file marker + \edef\qr@datatowrite{#2}% + \ifnum#1=1 + \qr@storetomatrix{#3}{\theqr@i}{\theqr@j}{\qr@black}% + \else + \qr@storetomatrix{#3}{\theqr@i}{\theqr@j}{\qr@white}% + \fi +}% + +\newif\ifqr@rightcol +\newif\ifqr@goingup + +\def\qr@writedata@hex#1#2{% + % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc. + % #2 = a string consisting of bytes to write into the matrix, in two-char hex format. + \setcounter{qr@i}{\qr@numberofrowsinmatrix{#1}}% + \setcounter{qr@j}{\qr@numberofcolsinmatrix{#1}}% + \qr@rightcoltrue% + \qr@goinguptrue% + \edef\qr@argument{{#1}(#2\relax\relax\relax)}% + \xa\qr@writedata@hex@recursive\qr@argument% +}% + +\def\qr@writedata@hex@recursive#1(#2#3#4){% + % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc. + % (qr@i,qr@j) = position to write in LaTeX counters + % #2#3#4 contains the hex codes of the bytes to be written, plus \relax\relax\relax + % as an end-of-file marker + \edef\qr@testii{#2}% + \ifx\qr@testii\qr@relax% + % #2 is \relax, so there is nothing more to write. + \relax + \let\qr@next=\relax + \else + % #2 is not \relax, so there is another byte to write. + \qr@hextobinary[8]{\bytetowrite}{#2#3}% + \xdef\qr@datatowrite{\bytetowrite\relax}% %Add terminating "\relax" + \qr@writedata@recursive{#1}% %This function actually writes the 8 bits. + \edef\qr@argument{{#1}(#4)}% + \xa\def\xa\qr@next\xa{\xa\qr@writedata@hex@recursive\qr@argument}% %Call self to write the next bit. + \fi + \qr@next +}% + +\def\qr@writedata#1#2{% + % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc. + % #2 = a string consisting of 0's and 1's to write into the matrix. + \setcounter{qr@i}{\qr@numberofrowsinmatrix{#1}}% + \setcounter{qr@j}{\qr@numberofcolsinmatrix{#1}}% + \qr@rightcoltrue + \qr@goinguptrue + \edef\qr@datatowrite{#2\relax}% + \qr@writedata@recursive{#1}% +}% + +\def\qr@@blank{\qr@blank}% + +\def\qr@writedata@recursive#1{% + % #1 = matrix name + % (qr@i,qr@j) = position to write in (LaTeX counters) + % \qr@datatowrite contains the bits to be written, plus '\relax' as an end-of-file marker + \xa\let\xa\squarevalue\csname #1@\theqr@i @\theqr@j\endcsname% + \ifx\squarevalue\qr@@blank + %Square is blank, so write data in it. + \xa\qr@writebit\xa(\qr@datatowrite){#1}% + %The \qr@writebit macro not only writes the first bit of \qr@datatowrite into the matrix, + %but also removes the bit from the 'bitstream' of \qr@datatowrite. + \fi + %Now adjust our position in the matrix. + \ifqr@rightcol + %From the right-hand half of the two-bit column, we always move left. Easy peasy. + \addtocounter{qr@j}{-1}% + \qr@rightcolfalse + \else + %If we're in the left-hand column, things are harder. + \ifqr@goingup + %First, suppose we're going upwards. + \ifnum\c@qr@i>1\relax% + %If we're not in the first row, things are easy. + %We move one to the right and one up. + \addtocounter{qr@j}{1}% + \addtocounter{qr@i}{-1}% + \qr@rightcoltrue + \else + %If we are in the first row, then we move to the left, + %and we are now in the right-hand column on a downward pass. + \addtocounter{qr@j}{-1}% + \qr@goingupfalse + \qr@rightcoltrue + \fi + \else + %Now, suppose we're going downwards. + \xa\ifnum\qr@size>\c@qr@i\relax% + %If we're not yet in the bottom row, things are easy. + %We move one to the right and one down. + \addtocounter{qr@j}{1}% + \addtocounter{qr@i}{1}% + \qr@rightcoltrue + \else + %If we are in the bottom row, then we move to the left, + %and we are now in the right-hand column on an upward pass. + \addtocounter{qr@j}{-1}% + \qr@rightcoltrue + \qr@goinguptrue + \fi + \fi + %One problem: what if we just moved into the 7th column? + %Das ist verboten. + %If we just moved (left) into the 7th column, we should move on into the 6th column. + \ifnum\c@qr@j=7\relax% + \setcounter{qr@j}{6}% + \fi + \fi + %Now check whether there are any more bits to write. + \ifx\qr@datatowrite\qr@relax + % \qr@datatowrite is just `\relax', so we're done. + \let\qr@next=\relax + \relax + \else + % Write some more! + \def\qr@next{\qr@writedata@recursive{#1}}% + \fi + \qr@next +}% + +\def\qr@writeremainderbits#1{% + % #1 = name of a matrix that has been prepared and partly filled. + % (qr@i,qr@j) = position to write in LaTeX counters + \xa\ifnum\qr@numremainderbits>0\relax + \def\qr@datatowrite{}% + \qr@for \i = 1 to \qr@numremainderbits by 1% + {\g@addto@macro{\qr@datatowrite}{0}}% + \g@addto@macro{\qr@datatowrite}{\relax}% terminator + \qr@writedata@recursive{#1}% + \fi +}% + +\newif\ifqr@cellinmask + +\def\qr@setmaskingfunction#1{% + % #1 = 1 decimal digit for the mask. (I see no reason to use the 3-bit binary code.) + % The current position is (\themaski,\themaskj), with indexing starting at 0. + \edef\qr@maskselection{#1}% + \xa\ifcase\qr@maskselection\relax + %Case 0: checkerboard + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski+\themaskj,2)% + \qr@a=\c@maski% + \advance\qr@a by \c@maskj% + \qr@b=\qr@a% + \divide\qr@b by 2% + \multiply\qr@b by 2% + \advance\qr@a by -\qr@b% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 1: horizontal stripes + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski,2)% + \ifodd\c@maski\relax% + \def\qr@maskfunctionresult{1}% + \else% + \def\qr@maskfunctionresult{0}% + \fi% + }% + \or + %Case 2: vertical stripes + \def\qr@parsemaskingfunction{% + % Compute mod(\themaskj,3)% + \qr@a=\c@maskj% + \divide\qr@a by 3% + \multiply\qr@a by 3% + \advance\qr@a by -\c@maskj% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 3: diagonal stripes + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski+\themaskj,3)% + \qr@a=\c@maski% + \advance\qr@a by \c@maskj% + \qr@b=\qr@a% + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@b by -\qr@a% + \edef\qr@maskfunctionresult{\the\qr@b}% + }% + \or + %Case 4: wide checkerboard + \def\qr@parsemaskingfunction{% + % Compute mod(floor(\themaski/2) + floor(\themaskj/3),2) % + \qr@a=\c@maski% + \divide\qr@a by 2% + \qr@b=\c@maskj% + \divide\qr@b by 3% + \advance\qr@a by \qr@b% + \qr@b=\qr@a% + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@a by -\qr@b% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 5: quilt + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski*\themaskj,2) + mod(\themaski*\themaskj,3) % + \qr@a=\c@maski% + \multiply\qr@a by \c@maskj% + \qr@b=\qr@a% + \qr@c=\qr@a% + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@a by -\qr@c% (result will be -mod(i*j,2), which is negative.) + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@b by -\qr@c% (result will be -mod(i*j,3), which is negative.) + \advance\qr@a by \qr@b% (result is negative of what's in the spec.) + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 6: arrows + \def\qr@parsemaskingfunction{% + % Compute mod( mod(\themaski*\themaskj,2) + mod(\themaski*\themaskj,3) , 2 ) % + \qr@a=\c@maski% + \multiply\qr@a by \c@maskj% + \qr@b=\qr@a% + \qr@c=\qr@a% + \multiply\qr@c by 2% % \qr@c equals 2*i*j. + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@c by -\qr@a% Now \qr@c equals i*j + mod(i*j,2). + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@c by -\qr@b% (Now \qr@c equals mod(i*j,2) + mod(i*j,3). + \qr@a=\qr@c% + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@c by-\qr@a% + \edef\qr@maskfunctionresult{\the\qr@c}% + }% + \or + %Case 7: shotgun + \def\qr@parsemaskingfunction{% + % Compute mod( mod(\themaski+\themaskj,2) + mod(\themaski*\themaskj,3) , 2 ) % + \qr@a=\c@maski% + \advance\qr@a by \c@maskj% %So \qr@a = i+j + \qr@b=\c@maski% + \multiply\qr@b by \c@maskj% %So \qr@b = i*j + \qr@c=\qr@a% + \advance\qr@c by \qr@b% So \qr@c = i+j+i*j + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@c by -\qr@a% So \qr@c = mod(i+j,2) + i*j + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@c by -\qr@b% So \qr@c = mod(i+j,2) + mod(i*j,3) + \qr@a=\qr@c% + \divide\qr@c by 2% + \multiply\qr@c by 2% + \advance\qr@a by -\qr@c% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \fi +}% + + +\def\qr@checkifcellisinmask{% + % The current position is (\i,\j), in TeX counts, + % but the LaTeX counters (maski,maskj) should contain + % the current position with indexing starting at 0. + % That is, maski = \i-1 and maskj = \j-1. + % + % \qr@parsemaskingfunction must have been set by a call to \qr@setmaskingfunction + \qr@parsemaskingfunction + \xa\ifnum\qr@maskfunctionresult=0\relax + \qr@cellinmasktrue + \else + \qr@cellinmaskfalse + \fi +}% + +\newcounter{maski}% +\newcounter{maskj}% + +\def\qr@applymask#1#2#3{% + % #1 = name of a matrix that should be filled out completely + % except for the format and/or version information. + % #2 = name of a new matrix to contain the masked version + % #3 = 1 decimal digit naming the mask + \qr@createduplicatematrix{#2}{#1}% + \qr@setmaskingfunction{#3}% + \setcounter{maski}{-1}% + \qr@for \i = 1 to \qr@size by 1% + {\stepcounter{maski}% + \setcounter{maskj}{-1}% + \qr@for \j = 1 to \qr@size by 1% + {\stepcounter{maskj}% + \qr@checkifcellisinmask + \ifqr@cellinmask + \qr@checkifcurrentcellcontainsdata{#2}% + \ifqr@currentcellcontainsdata + \qr@flipcurrentcell{#2}% + \fi + \fi + }% + }% +}% + +\newif\ifqr@currentcellcontainsdata +\qr@currentcellcontainsdatafalse + +\def\qr@@white{\qr@white}% +\def\qr@@black{\qr@black}% + +\def\qr@checkifcurrentcellcontainsdata#1{% + % #1 = name of matrix + \qr@currentcellcontainsdatafalse + \xa\ifx\csname #1@\the\i @\the\j\endcsname\qr@@white + \qr@currentcellcontainsdatatrue + \fi + \xa\ifx\csname #1@\the\i @\the\j\endcsname\qr@@black + \qr@currentcellcontainsdatatrue + \fi +}% + +\def\qr@flipped@black{\qr@black}% +\def\qr@flipped@white{\qr@white}% + +\def\qr@flipcurrentcell#1{% + % #1 = name of matrix + % (\i, \j) = current position, in TeX counts. + % This assumes the cell contains data, either black or white! + \xa\ifx\csname #1@\the\i @\the\j\endcsname\qr@@white + \qr@storetomatrix{#1}{\the\i}{\the\j}{\qr@flipped@black}% + \else + \qr@storetomatrix{#1}{\the\i}{\the\j}{\qr@flipped@white}% + \fi +}% + +\def\qr@chooseandapplybestmask#1{% + % #1 = name of a matrix that should be filled out completely + % except for the format and/or version information. + % This function applies all eight masks in succession, + % calculates their penalties, and remembers the best. + % The number indicating which mask was used is saved in \qr@mask@selected. + \qr@createduplicatematrix{originalmatrix}{#1}% + \message{^^J}% + \gdef\qr@currentbestmask{0}% + \qr@for \i = 1 to 7 by 1% + {\message{^^J}% + \xa\xa\xa\ifnum\xa\qr@penalty\xa<\qr@currentbestpenalty\relax + %We found a better mask. + \xdef\qr@currentbestmask{\the\i}% + \qr@createduplicatematrix{#1}{currentmasked}% + \xdef\qr@currentbestpenalty{\qr@penalty}% + \fi + }% + \xdef\qr@mask@selected{\qr@currentbestmask}% + \message{^^J}% +}% + + +\def\qr@Ni{3}% +\def\qr@Nii{3}% +\def\qr@Niii{40}% +\def\qr@Niv{10}% +\def\qr@fiveones{11111}% +\def\qr@fivezeros{11111}% +\def\qr@twoones{11}% +\def\qr@twozeros{00}% +\def\qr@finderA{00001011101}% +\def\qr@finderB{10111010000}% +\def\qr@finderB@three{1011101000}% +\def\qr@finderB@two{101110100}% +\def\qr@finderB@one{10111010}% +\def\qr@finderB@zero{1011101}% +\newif\ifqr@stringoffive +\def\qr@addpenaltyiii{% + \addtocounter{penaltyiii}{\qr@Niii}% +}% +\newcounter{totalones}% +\newcounter{penaltyi}% +\newcounter{penaltyii}% +\newcounter{penaltyiii}% +\newcounter{penaltyiv}% +\def\qr@evaluatemaskpenalty#1{% + % #1 = name of a matrix that we will test for the penalty + % according to the specs. + \setcounter{penaltyi}{0}% + \setcounter{penaltyii}{0}% + \setcounter{penaltyiii}{0}% + \setcounter{penaltyiv}{0}% + \bgroup%localize the meanings we give to the symbols + \def\qr@black{1}\def\qr@white{0}% + \def\qr@black@fixed{1}\def\qr@white@fixed{0}% + \def\qr@format@square{0}% This is not stated in the specs, but seems + % to be the standard implementation. + \def\qr@blank{0}% These would be any bits at the end. + % + \setcounter{totalones}{0}% + \qr@for \i=1 to \qr@size by 1% + {\def\qr@lastfive{z}% %The z is a dummy, that will be removed before any testing. + \qr@stringoffivefalse + \def\qr@lasttwo@thisrow{z}% %The z is a dummy. + \def\qr@lasttwo@nextrow{z}% %The z is a dummy. + \def\qr@lastnine{z0000}% %The 0000 stands for the white space to the left. The z is a dummy. + \def\qr@ignore@finderB@at{0}% + \qr@for \j=1 to \qr@size by 1% + {\edef\qr@newbit{\qr@matrixentry{#1}{\the\i}{\the\j}}% + % + % LASTFIVE CODE FOR PENALTY 1 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastfive\xa{\qr@newbit}% + \ifnum\j<5\relax% + %Not yet on the 5th entry. + %Don't do any testing. + \else + % 5th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastfive% + \ifx\qr@lastfive\qr@fiveones% + \ifqr@stringoffive% + %This is a continuation of a previous block of five or more 1's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 1's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + \ifx\qr@lastfive\qr@fivezeros% + \ifqr@stringoffive + %This is a continuation of a previous block of five or more 0's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 0's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + %This is not a string of five 1's or five 0's. + \global\qr@stringoffivefalse + \fi + \fi + \fi + % + % 2x2 BLOCKS FOR PENALTY 2 + % Every 2x2 block of all 1's counts for \qr@Nii penalty points. + % We do not need to run this test in the last row. + \xa\ifnum\xa\i\xa<\qr@size\relax + \xa\g@addto@macro\xa\qr@lasttwo@thisrow\xa{\qr@newbit}% + %Compute \qr@iplusone + \qr@a=\i\relax% + \advance\qr@a by 1% + \edef\qr@iplusone{\the\qr@a}% + % + \edef\qr@nextrowbit{\qr@matrixentry{#1}{\qr@iplusone}{\the\j}}% + \xa\g@addto@macro\xa\qr@lasttwo@nextrow\xa{\qr@nextrowbit}% + \ifnum\j<2\relax% + %Still in the first column; no check. + \else + %Second column or later. Remove the old bits, and then test. + \qr@removefirsttoken\qr@lasttwo@thisrow + \qr@removefirsttoken\qr@lasttwo@nextrow + \ifx\qr@lasttwo@thisrow\qr@twoones + \ifx\qr@lasttwo@nextrow\qr@twoones + \addtocounter{penaltyii}{\qr@Nii}% + \fi + \else + \ifx\qr@lasttwo@thisrow\qr@twozeros + \ifx\qr@lasttwo@nextrow\qr@twozeros + \addtocounter{penaltyii}{\qr@Nii}% + \fi + \fi + \fi + \fi + \fi + % + % LASTNINE CODE FOR PENALTY 3 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastnine\xa{\qr@newbit}% + \ifnum\j<7\relax% + %Not yet on the 7th entry. + %Don't do any testing. + \else + % 7th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastnine + \xa\ifnum\qr@size=\j\relax% + % Last column. Any of the following should count: + % 1011101 (\qr@finderB@zero) + % 10111010 (\qr@finderB@one) + % 101110100 (\qr@finderB@two) + % 1011101000 (\qr@finderB@three) + % 10111010000 (\qr@finderB) + \ifx\qr@lastnine\qr@finderB + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@three + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@two + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@one + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@zero + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + \else + \ifx\qr@lastnine\qr@finderA% %Matches 0000 1011101 + \qr@addpenaltyiii + %Also, we record our discovery, so that we can't count this pattern again + %if it shows up four columns later as 1011101 0000. + % + %Set \qr@ignore@finderB@at to \j+4. + \qr@a=\j\relax% + \advance\qr@a by 4% + \xdef\qr@ignore@finderB@at{\the\qr@a}% + \else + \ifx\qr@lastfive\qr@finderB% %Matches 1011101 0000. + \xa\ifnum\qr@ignore@finderB@at=\j\relax + %This pattern was *not* counted already earlier. + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + % + %COUNT 1's FOR PENALTY 4 + \xa\ifnum\qr@newbit=1\relax% + \stepcounter{totalones}% + \fi + }% end of j-loop + }% end of i-loop + % + %NOW WE ALSO NEED TO RUN DOWN THE COLUMNS TO FINISH CALCULATING PENALTIES 1 AND 3. + \qr@for \j=1 to \qr@size by 1% + {\def\qr@lastfive{z}% %The z is a dummy, that will be removed before any testing. + \qr@stringoffivefalse + \def\qr@lastnine{z0000}% %The 0000 stands for the white space to the left. The z is a dummy. + \def\qr@ignore@finderB@at{0}% + \qr@for \i=1 to \qr@size by 1% + {\edef\qr@newbit{\qr@matrixentry{#1}{\the\i}{\the\j}}% + % + % LASTFIVE CODE FOR PENALTY 1 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastfive\xa{\qr@newbit}% + \ifnum\i<5\relax% + %Not yet on the 5th entry. + %Don't do any testing. + \else + % 5th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastfive% + \ifx\qr@lastfive\qr@fiveones% + \ifqr@stringoffive% + %This is a continuation of a previous block of five or more 1's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 1's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + \ifx\qr@lastfive\qr@fivezeros% + \ifqr@stringoffive + %This is a continuation of a previous block of five or more 0's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 0's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + %This is not a string of five 1's or five 0's. + \global\qr@stringoffivefalse + \fi + \fi + \fi + % + % HAPPILY, WE DON'T NEED TO CALCULATE PENALTY 2 AGAIN. + % + % LASTNINE CODE FOR PENALTY 3 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastnine\xa{\qr@newbit}% + \ifnum\i<7\relax% + %Not yet on the 7th entry. + %Don't do any testing. + \else + % 7th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastnine + \xa\ifnum\qr@size=\i\relax% + % Last column. Any of the following should count: + % 1011101 (\qr@finderB@zero) + % 10111010 (\qr@finderB@one) + % 101110100 (\qr@finderB@two) + % 1011101000 (\qr@finderB@three) + % 10111010000 (\qr@finderB) + \ifx\qr@lastnine\qr@finderB + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@three + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@two + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@one + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@zero + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + \else + \ifx\qr@lastnine\qr@finderA% %Matches 0000 1011101 + \qr@addpenaltyiii + %Also, we record our discovery, so that we can't count this pattern again + %if it shows up four columns later as 1011101 0000. + % + %Set \qr@ignore@finderB@at to \i+4. + \qr@a=\i\relax% + \advance\qr@a by 4% + \xdef\qr@ignore@finderB@at{\the\qr@a}% + \else + \ifx\qr@lastfive\qr@finderB% %Matches 1011101 0000. + \xa\ifnum\qr@ignore@finderB@at=\i\relax + %This pattern was *not* counted already earlier. + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + % + }% end of i-loop + }% end of j-loop + \egroup% + % + %CALCULATE PENALTY 4 + %According to the spec, penalty #4 is computed as + % floor( |(i/n^2)-0.5|/0.05 ) + % where i is the total number of 1's in the matrix. + % This is equal to abs(20*i-10n^2) div n^2. + % + \qr@a=\c@totalones\relax + \multiply\qr@a by 20\relax + \qr@b=\qr@size\relax + \multiply\qr@b by \qr@size\relax + \qr@c=10\relax + \multiply\qr@c by \qr@b\relax + \advance\qr@a by -\qr@c\relax + \ifnum\qr@a<0\relax + \multiply\qr@a by -1\relax + \fi + \divide\qr@a by \qr@b\relax + \setcounter{penaltyiv}{\the\qr@a}% + % + %CALCULATE TOTAL PENALTY + \qr@a=\thepenaltyi\relax% + \advance\qr@a by \thepenaltyii\relax% + \advance\qr@a by \thepenaltyiii\relax% + \advance\qr@a by \thepenaltyiv\relax% + \edef\qr@penalty{\the\qr@a}% +}% + +\def\qr@removefirsttoken#1{% + %Removes the first token from the macro named in #1. + \edef\qr@argument{(#1)}% + \xa\qr@removefirsttoken@int\qr@argument% + \xdef#1{\qr@removefirsttoken@result}% +}% +\def\qr@removefirsttoken@int(#1#2){% + \def\qr@removefirsttoken@result{#2}% +}% + +\def\qr@writeformatstring#1#2{% + % #1 = matrix name + % #2 = binary string representing the encoded and masked format information + \setcounter{qr@i}{9}% + \setcounter{qr@j}{1}% + \edef\qr@argument{{#1}(#2\relax)}% + \xa\qr@writeformatA@recursive\qr@argument + % + \setcounter{qr@i}{\qr@numberofrowsinmatrix{#1}}% + \setcounter{qr@j}{9}% + \xa\qr@writeformatB@recursive\qr@argument +}% + +\def\qr@writeformatA@recursive#1(#2#3){% + % #1 = matrix name + % #2 = first bit of string + % #3 = rest of bitstream + % (qr@i,qr@j) = current (valid) position to write (in LaTeX counters) + \ifnum#2=1\relax + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@black@format}% + \else + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@white@format}% + \fi + % Now the tricky part--moving \i and \j to their next positions. + \ifnum\c@qr@j<9\relax + %If we're not yet in column 9, move right. + \stepcounter{qr@j}% + \ifnum\c@qr@j=7\relax + %But we skip column 7! + \stepcounter{qr@j}% + \fi + \else + %If we're in column 9, we move up. + \addtocounter{qr@i}{-1}% + \ifnum\c@qr@i=7\relax + %But we skip row 7! + \addtocounter{qr@i}{-1}% + \fi + \fi + %N.B. that at the end of time, this will leave us at invalid position (0,9). + %That makes for an easy test to know when we are done. + \ifnum\c@qr@i<1 + \let\qr@next=\relax + \else + \def\qr@next{\qr@writeformatA@recursive{#1}(#3)}% + \fi + \qr@next +}% + +\def\qr@writeformatB@recursive#1(#2#3){% + % #1 = matrix name + % #2 = first bit of string + % #3 = rest of bitstream + % (qr@i,qr@j) = current (valid) position to write (in LaTeX counters) + \ifnum#2=1\relax + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@black@format}% + \else + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@white@format}% + \fi + % Now the tricky part--moving counters i and j to their next positions. + \qr@a=\qr@size% + \advance\qr@a by -6\relax% + \ifnum\qr@a<\c@qr@i\relax + %If we're not yet in row n-6, move up. + \addtocounter{qr@i}{-1}% + \else + \ifnum\qr@a=\c@qr@i\relax + %If we're actually in row n-6, we jump to position (9,n-7). + \setcounter{qr@i}{9}% + %Set counter j equal to \qr@size-7. + \global\c@qr@j=\qr@size\relax% + \global\advance\c@qr@j by -7\relax% + \else + %Otherwise, we must be in row 9. + %In this case, we move right. + \stepcounter{qr@j}% + \fi + \fi + %N.B. that at the end of time, this will leave us at invalid position (9,n+1). + %That makes for an easy test to know when we are done. + \xa\ifnum\qr@size<\c@qr@j\relax + \let\qr@next=\relax + \else + \def\qr@next{\qr@writeformatB@recursive{#1}(#3)}% + \fi + \qr@next +}% + +\def\qr@writeversionstring#1#2{% + % #1 = matrix name + % #2 = binary string representing the encoded version information + % + % Plot the encoded version string into the matrix. + % This is only done for versions 7 and higher. + \xa\ifnum\qr@version>6\relax + %Move to position (n-8,6). + \setcounter{qr@i}{\qr@size}\relax% + \addtocounter{qr@i}{-8}\relax% + \setcounter{qr@j}{6}% + \edef\qr@argument{{#1}(#2\relax)}% + \xa\qr@writeversion@recursive\qr@argument + \fi +}% + +\def\qr@writeversion@recursive#1(#2#3){% + % #1 = matrix name + % #2 = first bit of string + % #3 = rest of bitstream + % (qr@i,qr@j) = current (valid) position to write (in LaTeX counters) + % + % The version information is stored symmetrically in the matrix + % In two transposed regions, so we can write both at the same time. + % In the comments, we describe what happens in the lower-left region, + % not the upper-right. + % + %Set \qr@topline equal to n-10. + \qr@a=\qr@size\relax% + \advance\qr@a by -10\relax% + \edef\qr@topline{\the\qr@a}% + % + \ifnum#2=1\relax + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@black@format}% + \qr@storetomatrix{#1}{\theqr@j}{\theqr@i}{\qr@black@format}% + \else + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@white@format}% + \qr@storetomatrix{#1}{\theqr@j}{\theqr@i}{\qr@white@format}% + \fi + % Now the tricky part--moving counters i and j to their next positions. + \addtocounter{qr@i}{-1}% + \xa\ifnum\qr@topline>\c@qr@i\relax + %We've overshot the top of the region. + %We need to move left one column and down three. + \addtocounter{qr@j}{-1}% + \addtocounter{qr@i}{3}% + \fi + %N.B. that at the end of time, this will leave us at invalid position (n-8,0). + %That makes for an easy test to know when we are done. + \ifnum\c@qr@j<1\relax + \let\qr@next=\relax + \else + \def\qr@next{\qr@writeversion@recursive{#1}(#3)}% + \fi + \qr@next +}% +% \end{macrocode} +% +% \subsection{Encoding and error correction} +% \begin{macrocode} +\newcounter{qr@hexchars}% + +\def\qr@string@binarytohex#1{% + \qr@binarytohex{\qr@hex@result}{#1}% +}% + +\def\qr@encode@binary#1{% + % #1 = string of ascii characters, to be converted into bitstream + % + % We do this one entirely in hex, rather than binary, because we can. + \edef\qr@plaintext{#1}% + % + %First, the mode indicator. + \def\qr@codetext{4}% %This means `binary' + % + %Next, the character count. + \qr@getstringlength{\qr@plaintext}% + %Set \qr@charactercountlengthinhex to \qr@charactercountbits@byte/4% + \qr@a=\qr@charactercountbits@byte\relax% + \divide \qr@a by 4\relax% + \edef\qr@charactercountlengthinhex{\the\qr@a}% + \qr@decimaltohex[\qr@charactercountlengthinhex]{\qr@charactercount}{\qr@stringlength}% + \xa\g@addto@macro\xa\qr@codetext\xa{\qr@charactercount}% + % + %Now comes the actual data. + \edef\qr@argument{(,\qr@plaintext\relax\relax\relax)}% + \xa\qr@encode@ascii@recursive\qr@argument% + % + %Now the terminator. + \g@addto@macro\qr@codetext{0}% %This is '0000' in binary. + % + %There is no need to pad bits to make a multiple of 8, + %because the data length is already 4 + 8 + 8n + 4. + % + %Now add padding codewords if needed. + \setcounter{qr@hexchars}{0}% + \qr@getstringlength{\qr@codetext}% + \setcounter{qr@hexchars}{\qr@stringlength}% + %Set \qr@numpaddingcodewords equal to \qr@totaldatacodewords - qr@hexchars/2. + \qr@a=-\c@qr@hexchars\relax + \divide\qr@a by 2\relax + \advance\qr@a by \qr@totaldatacodewords\relax + \edef\qr@numpaddingcodewords{\the\qr@a}% + % + \xa\ifnum\qr@numpaddingcodewords<0% + \edef\ds{ERROR: Too much data! Over by \qr@numpaddingcodewords bytes.}\show\ds% + \fi% + \xa\ifnum\qr@numpaddingcodewords>0% + \qr@for \i = 2 to \qr@numpaddingcodewords by 2% + {\g@addto@macro{\qr@codetext}{ec11}}% + \xa\ifodd\qr@numpaddingcodewords\relax% + \g@addto@macro{\qr@codetext}{ec}% + \fi% + \fi% +}% + +\def\qr@encode@ascii@recursive(#1,#2#3){% + % #1 = hex codes translated so far + % #2 = next plaintext character to translate + % #3 = remainder of plaintext + \edef\qr@testii{#2}% + \ifx\qr@testii\qr@relax% + % All done! + \g@addto@macro\qr@codetext{#1}% + \else% + % Another character to translate. + \edef\qr@asciicode{\number`#2}% + \qr@decimaltohex[2]{\qr@newhexcodes}{\qr@asciicode}% + \edef\qr@argument{(#1\qr@newhexcodes,#3)}% + %\show\qr@argument + \xa\qr@encode@ascii@recursive\qr@argument% + \fi% +}% + +\def\qr@splitcodetextintoblocks{% + \setcounter{qr@i}{0}% + \qr@for \j = 1 to \qr@numshortblocks by 1% + {\stepcounter{qr@i}% + \qr@splitoffblock{\qr@codetext}{\theqr@i}{\qr@shortblock@size}% + }% + \xa\ifnum\qr@numlongblocks>0\relax% + \qr@for \j = 1 to \qr@numlongblocks by 1% + {\stepcounter{qr@i}% + \qr@splitoffblock{\qr@codetext}{\theqr@i}{\qr@longblock@size}% + }% + \fi% +}% + +\def\qr@splitoffblock#1#2#3{% + % #1 = current codetext in hexadecimal + % #2 = number to use in csname "\datablock@#2". + % #3 = number of bytes to split off + \message{}% + \xa\gdef\csname datablock@#2\endcsname{}% %This line is important! + \qr@for \i = 1 to #3 by 1% + {\edef\qr@argument{{#2}(#1)}% + \xa\qr@splitoffblock@int\qr@argument% + }% +}% + +\def\qr@splitoffblock@int#1(#2#3#4){% + % #1 = number to use in csname "\datablock@#1". + % #2#3 = next byte to split off + % #4 = remaining text + % + % We add the next byte to "\datablock@#1", + % and we remove it from the codetext. + \xa\xdef\csname datablock@#1\endcsname{\csname datablock@#1\endcsname#2#3}% + \xdef\qr@codetext{#4}% +}% + +\def\qr@createerrorblocks{% + \qr@for \ii = 1 to \qr@numblocks by 1% + {\message{}% + \FX@generate@errorbytes{\csname datablock@\the\ii\endcsname}{\qr@num@eccodewords}% + \xa\xdef\csname errorblock@\the\ii\endcsname{\FX@errorbytes}% + }% +}% + +\def\qr@interleave{% + \setcounter{qr@i}{0}% + \def\qr@interleaved@text{}% + \message{0\relax% + \message{\qr@longblock@size.>}% + \else + \message{.>}% + \fi + \message{}% +}% + +\def\qr@writefromblock#1#2{% + % #1 = either 'datablock' or 'errorblock' + % #2 = block number, in {1,...,\qr@numblocks}% + \edef\qr@argument{(\csname #1@#2\endcsname\relax\relax\relax)}% + \xa\qr@writefromblock@int\qr@argument + \xa\xdef\csname #1@#2\endcsname{\qr@writefromblock@remainder}% +}% + +\def\qr@writefromblock@int(#1#2#3){% + % #1#2 = first byte (in hex) of text, which will be written to \qr@interleaved@text + % #3 = remainder, including \relax\relax\relax terminator. + \g@addto@macro{\qr@interleaved@text}{#1#2}% + \qr@writefromblock@intint(#3)% +}% + +\def\qr@writefromblock@intint(#1\relax\relax\relax){% + \xdef\qr@writefromblock@remainder{#1}% +}% +% \end{macrocode} +% +% \subsection{Encoding format and version information} +% \begin{macrocode} +\let\xa=\expandafter +\makeatletter + +\def\qr@preface@macro#1#2{% + % #1 = macro name + % #2 = text to add to front of macro + \def\qr@tempb{#2}% + \xa\xa\xa\gdef\xa\xa\xa#1\xa\xa\xa{\xa\qr@tempb #1}% +}% + +\newif\ifqr@leadingcoeff +\def\qr@testleadingcoeff(#1#2){% + % Tests whether the leading digit of #1#2 is 1. + \ifnum#1=1\relax + \qr@leadingcoefftrue + \else + \qr@leadingcoefffalse + \fi +}% + +\def\qr@polynomialdivide#1#2{% + \edef\qr@numerator{#1}% + \edef\qr@denominator{#2}% + \qr@divisiondonefalse% + \xa\xa\xa\qr@oneroundofdivision\xa\xa\xa{\xa\qr@numerator\xa}\xa{\qr@denominator}% +}% + +\def\@qr@empty{}% +\def\qr@oneroundofdivision#1#2{% + % #1 = f(x), of degree n + % #2 = g(x), of degree m + % Obtains a new polynomial h(x), congruent to f(x) modulo g(x), + % but of degree at most n-1. + % + % If leading coefficient of f(x) is 1, subtracts off g(x) * x^(n-m). + % If leading coefficient of f(x) is 0, strips off that leading zero. + % + \qr@testleadingcoeff(#1)% + \ifqr@leadingcoeff + \qr@xorbitstrings{#1}{#2}% + \ifqr@xorfailed + %If xor failed, that means our #1 was already the remainder! + \qr@divisiondonetrue + \edef\qr@theremainder{#1}% + \else + %xor succeeded. We need to recurse. + \xa\xa\xa\edef\xa\xa\xa\qr@numerator\xa\xa\xa{\xa\qr@stripleadingzero\xa(\qr@xorresult)}% + \fi + \else + \xa\def\xa\qr@numerator\xa{\qr@stripleadingzero(#1)}% + \ifx\qr@numerator\@qr@empty + \qr@divisiondonetrue + \def\qr@theremainder{0}% + \fi + \fi + \ifqr@divisiondone + \relax + \else + \xa\qr@oneroundofdivision\xa{\qr@numerator}{#2}% + \fi +}% + +\def\qr@stripleadingzero(0#1){#1}%Strips off a leading zero. + +\newif\ifqr@xorfailed% This flag will trigger when #2 is longer than #1. + +\def\qr@xorbitstrings#1#2{% + % #1 = bitstring + % #2 = bitstring no longer than #1 + \qr@xorfailedfalse + \edef\qr@argument{(,#1\relax\relax)(#2\relax\relax)}% + \xa\qr@xorbitstrings@recursive\qr@argument + %\qr@xorbitstrings@recursive(,#1\relax\relax)(#2\relax\relax)% +}% + +\def\qr@xorbitstrings@recursive(#1,#2#3)(#4#5){% + % #1#2#3 is the first bitstring, xor'ed up through #1. + % #4#5 is the remaining portion of the second bitstring. + \def\qr@testii{#2}% + \def\qr@testiv{#4}% + \ifx\qr@testii\qr@relax + % #1 contains the whole string. + % Now if #4 is also \relax, that means the two strings started off with equal lengths. + % If, however, #4 is not \relax, that means the second string was longer than the first, a problem. + \ifx\qr@testiv\qr@relax + %No problem. We are done. + \qr@xorbit@saveresult(#1#2#3)% + \else + %Problem! The second string was longer than the first. + \qr@xorfailedtrue + \def\qr@xorresult{}% + \fi + \else + % There is still a bit to manipulate in #2. + % Check whether #4 contains anything. + \ifx\qr@testiv\qr@relax + % No, #4 is empty. We are done. "#2#3" contains the remainder of the first string, + % which we append untouched and then strip off the two \relax-es. + \qr@xorbit@saveresult(#1#2#3)% + \else + % Yes, #4 still has something to XOR. Do the task. + \ifnum#2=#4\relax + \qr@xorbitstrings@recursive(#1% + 0,#3)(#5)% + \else + \qr@xorbitstrings@recursive(#1% + 1,#3)(#5)% + \fi + \fi + \fi +}% + +\def\qr@xorbit@saveresult(#1\relax\relax){% + %Strips off the extra '\relax'es at the end. + \def\qr@xorresult{#1}% +}% + +\newif\ifqr@divisiondone + +\def\qr@BCHcode#1{% + \edef\qr@formatinfo{#1}% + \def\qr@formatinfopadded{\qr@formatinfo 0000000000}% + \def\qr@divisor{10100110111}% + \qr@divisiondonefalse + \qr@polynomialdivide{\qr@formatinfopadded}{\qr@divisor}% + % + \qr@getstringlength{\qr@theremainder}% + %Run loop from stringlength+1 to 10. + \qr@a=\qr@stringlength\relax% + \advance\qr@a by 1\relax% + \qr@for \i = \qr@a to 10 by 1% + {\qr@preface@macro{\qr@theremainder}{0}% + \xdef\qr@theremainder{\qr@theremainder}% + }% + \edef\qr@BCHresult{\qr@formatinfo\qr@theremainder}% +}% + +\def\qr@formatmask{101010000010010}% + +\def\qr@encodeandmaskformat#1{% + \qr@BCHcode{#1}% + \qr@xorbitstrings{\qr@BCHresult}{\qr@formatmask}% + \edef\qr@format@bitstring{\qr@xorresult}% +}% + +\def\qr@Golaycode#1{% + % #1 = 6-bit version number + \edef\qr@versioninfo{#1}% + \def\qr@versioninfopadded{\qr@versioninfo 000000000000}% %Append 12 zeros. + \def\qr@divisor{1111100100101}% + \qr@divisiondonefalse + \qr@polynomialdivide{\qr@versioninfopadded}{\qr@divisor}% + % + \qr@getstringlength{\qr@theremainder}% + %Run loop from stringlength+1 to 12. + \qr@a=\qr@stringlength\relax% + \advance\qr@a by 1\relax% + \qr@for \i = \qr@a to 12 by 1% + {\qr@preface@macro{\qr@theremainder}{0}% + \xdef\qr@theremainder{\qr@theremainder}% + }% + \edef\qr@Golayresult{\qr@versioninfo\qr@theremainder}% +}% +% \end{macrocode} +% +% \subsection{Error correction} +% The error-correction code is defined over $\F_{256}=GF(256)$, +% the finite field of order $256$. +% The QR specification encodes this field as $\F_2[X]/(X^8+X^4+X^3+X^2+1)$; +% in other words, each field element is an 8-bit binary string representing +% an integer between 0 and 255. +% +% We represent these 8-bit strings as two hexadecimal characters; +% for example, {\tt 5a} represents {\tt 01011010}. +% Because addition is done by xor-ing the bitstrings, +% we can define addition on hexadecimal characters. +% Since there are only $16^2$ possibilities, +% we create a lookup table. +% \begin{macrocode} +\def\F@result{}% + +\def\qr@xorbitstring#1#2#3{% + % #1 = new macro to receive result + % #2, #3 = bitstrings to xor. The second can be shorter than the first. + \def\qr@xor@result{}% + \edef\qr@argument{(#2\relax\relax)(#3\relax\relax)}% + \xa\qr@xorbitstring@recursive\qr@argument% + \edef#1{\qr@xor@result}% +}% +\def\qr@xorbitstring@recursive(#1#2)(#3#4){% + \edef\qr@testi{#1}% + \ifx\qr@testi\qr@relax% + %Done. + \let\qr@next=\relax% + \else + \if#1#3\relax + \g@addto@macro{\qr@xor@result}{0}% + \else + \g@addto@macro{\qr@xor@result}{1}% + \fi + \edef\qr@next{\noexpand\qr@xorbitstring@recursive(#2)(#4)}% + \fi + \qr@next +} + +\def\F@addchar@raw#1#2{% + %Add two hexadecimal digits using bitwise xor + \qr@hextobinary[4]{\qr@summandA}{#1}% + \qr@hextobinary[4]{\qr@summandB}{#2}% + \qr@xorbitstring{\F@result}{\qr@summandA}{\qr@summandB}% + \qr@binarytohex[1]{\F@result}{\F@result}% +}% + +\def\qr@canceltwos#1{% + \edef\qr@argument{(#1\relax\relax)}% + \xa\qr@canceltwos@int\qr@argument% +}% + +\def\qr@canceltwos@int(#1#2){% + \xa\qr@canceltwos@recursion(,#1#2)% +}% + +\def\qr@canceltwos@recursion(#1,#2#3){% + \def\qr@testii{#2}% + \ifx\qr@testii\qr@relax + %Cancelling complete. + \qr@striptworelaxes(#1#2#3)% + %Now \F@result contains the answer. + \else + \relax + \ifnum#2=2\relax + \qr@canceltwos@recursion(#10,#3)% + \else + \qr@canceltwos@recursion(#1#2,#3)% + \fi + \fi +}% + +\def\qr@striptworelaxes(#1\relax\relax){% + \gdef\F@result{#1}% +}% + +\qr@for \i = 0 to 15 by 1% + {\qr@decimaltohex[1]{\qr@tempa}{\the\i}% + \qr@for \j = 0 to 15 by 1% + {\qr@decimaltohex[1]{\qr@tempb}{\the\j}% + \F@addchar@raw\qr@tempa\qr@tempb + \xa\xdef\csname F@addchar@\qr@tempa\qr@tempb\endcsname{\F@result}% + }% + }% + +\def\F@addchar#1#2{% + \xa\def\xa\F@result\xa{\csname F@addchar@#1#2\endcsname}% +}% + +\def\F@addstrings#1#2{% + \edef\qr@argument{(,#1\relax\relax)(#2\relax\relax)}% + \xa\F@addstrings@recursion\qr@argument% +}% + +\def\F@addstrings@recursion(#1,#2#3)(#4#5){% + %Adds two hexadecimal strings, bitwise, from left to right. + %The second string is allowed to be shorter than the first. + \def\qr@testii{#2}% + \def\qr@testiv{#4}% + \ifx\qr@testii\qr@relax + %The entire string has been processed. + \gdef\F@result{#1}% + \else + \ifx\qr@testiv\qr@relax + %The second string is over. + \qr@striptworelaxes(#1#2#3)% + %Now \F@result contains the answer. + \else + %We continue to add. + \F@addchar{#2}{#4}% + \edef\qr@argument{(#1\F@result,#3)(#5)}% + \xa\F@addstrings@recursion\qr@argument% + \fi + \fi +}% +% \end{macrocode} +% Now we handle multiplication. +% Our approach to multiplying $a,b\in\F_{256}$ +% is to take discrete logarithms (with 2 as our base), +% add the logarithms, and then take the antilog. +% We first create a log table. +% \begin{macrocode} +\gdef\F@stripleadingzero(0#1){\edef\F@result{#1}}% + +\setcounter{qr@i}{0}% +\def\qr@poweroftwo{1}% +\qr@for \i = 1 to 254 by 1% + {\stepcounter{qr@i}% + \qr@a=\qr@poweroftwo\relax + \multiply\qr@a by 2\relax + \edef\qr@poweroftwo{\the\qr@a}% + %\show\qr@poweroftwo + \qr@decimaltohex[2]{\qr@poweroftwo@hex}{\qr@poweroftwo}% + \xa\ifnum\qr@poweroftwo>255\relax + %We need to bitwise add the polynomial represented by 100011101, i.e. 0x11d. + \F@addstrings{\qr@poweroftwo@hex}{11d}% %Now it should start with 0. + \xa\F@stripleadingzero\xa(\F@result)% %Now it should be two hex digits. + \edef\qr@poweroftwo@hex{\F@result}% %Save the hex version. + \qr@hextodecimal{\qr@poweroftwo}{\F@result}% + \fi + \xdef\qr@poweroftwo{\qr@poweroftwo}% + \xa\xdef\csname F@twotothe@\theqr@i\endcsname{\qr@poweroftwo@hex}% + \xa\xdef\csname F@logtwo@\qr@poweroftwo@hex\endcsname{\theqr@i}% + }% +\xa\xdef\csname F@twotothe@0\endcsname{01}% +\xa\xdef\csname F@logtwo@01\endcsname{0}% + +\def\F@twotothe#1{% + \xa\xdef\xa\F@result\xa{\csname F@twotothe@#1\endcsname}% +}% +\def\F@logtwo#1{% + \xa\xdef\xa\F@result\xa{\csname F@logtwo@#1\endcsname}% +}% + +\def\qr@zerozero{00}% + +\def\F@multiply#1#2{% + % #1 and #2 are two elements of F_256, + % given as two-character hexadecimal strings. + % Multiply them within F_256, and place the answer in \F@result + \edef\qr@argA{#1}% + \edef\qr@argB{#2}% + \ifx\qr@argA\qr@zerozero + \def\F@result{00}% + \else + \ifx\qr@argB\qr@zerozero + \def\F@result{00}% + \else + \xa\F@logtwo\xa{\qr@argA}% + \edef\qr@logA{\F@result}% + \xa\F@logtwo\xa{\qr@argB}% + \edef\qr@logB{\F@result}% + \xa\qr@a\xa=\qr@logA\relax% \qr@a = \qr@logA + \xa\advance\xa\qr@a\qr@logB\relax% \advance \qr@a by \qr@logB + \ifnum\qr@a>254\relax% + \advance\qr@a by -255\relax% + \fi% + \xa\F@twotothe\xa{\the\qr@a}% + % Now \F@result contains the product, as desired. + \fi + \fi +}% + + +\def\F@multiply#1#2{% + % #1 and #2 are two elements of F_256, + % given as two-character hexadecimal strings. + % Multiply them within F_256, and place the answer in \F@result + \edef\qr@argA{#1}% + \edef\qr@argB{#2}% + \ifx\qr@argA\qr@zerozero + \def\F@result{00}% + \else + \ifx\qr@argB\qr@zerozero + \def\F@result{00}% + \else + \xa\F@logtwo\xa{\qr@argA}% + \edef\qr@logA{\F@result}% + \xa\F@logtwo\xa{\qr@argB}% + \edef\qr@logB{\F@result}% + \xa\qr@a\xa=\qr@logA\relax% \qr@a = \qr@logA + \xa\advance\xa\qr@a\qr@logB\relax% \advance \qr@a by \qr@logB + \ifnum\qr@a>254\relax% + \advance\qr@a by -255\relax% + \fi% + \xa\F@twotothe\xa{\the\qr@a}% + % Now \F@result contains the product, as desired. + \fi + \fi +}% +% \end{macrocode} +% Having developed $\F_{256}$, we now turn to the real task. +% Each byte of data is read as an element of $\F_{256}$, +% and a sequence of bytes corresponds a polynomial in +% $\F_{256}[X]$. +% The Reed-Solomon code takes that codeword $f(X)\in \F_{256}[X]$ +% of degree $k$, divides $f(X)\cdot X^\ell$ by a fixed +% polynomial, +% and keeps the remainder $r(X)$ as the error-correction word. +% We therefore must implement polynomial division over $\F_{256}$. +% \begin{macrocode} +%These polynomials are represented as sequences of coefficients, +%from highest power to lowest, +%with each coefficient represented by two hexadecimal characters. + +\def\FX@getstringlength#1{% + %Count number of two-character coefficients + \setcounter{qr@i}{0}% + \xdef\qr@argument{(#1\relax\relax\relax)}% + \xa\FX@stringlength@recursive\qr@argument% + \xdef\stringresult{\arabic{qr@i}}% +}% + +\def\FX@stringlength@recursive(#1#2#3){% + \def\qr@testi{#1}% + \ifx\qr@testi\qr@relax + %we are done. + \else + \stepcounter{qr@i}% + %\showthe\c@qr@i + \qr@stringlength@recursive(#3)% + \fi +}% + +\newif\ifFX@leadingcoeff@zero +\def\FX@testleadingcoeff(#1#2#3){% + % Tests whether the leading coefficient of the hex-string #1#2#3 is '00'. + \edef\FX@leadingcoefficient{#1#2}% + \FX@leadingcoeff@zerofalse + \ifx\FX@leadingcoefficient\qr@zerozero + \FX@leadingcoeff@zerotrue + \fi +}% + +\newif\ifFX@divisiondone + +\newcounter{qr@divisionsremaining} %Keep track of how many divisions to go! +\def\FX@polynomialdivide#1#2{% + \edef\FX@numerator{#1}% + \edef\FX@denominator{#2}% + \qr@getstringlength\FX@numerator% + \setcounter{qr@divisionsremaining}{\qr@stringlength}% + \qr@getstringlength\FX@denominator% + \addtocounter{qr@divisionsremaining}{-\qr@stringlength}% + \addtocounter{qr@divisionsremaining}{2}% + \divide\c@qr@divisionsremaining by 2\relax% %2 hex chars per number + \FX@divisiondonefalse% + \xa\xa\xa\FX@polynomialdivide@recursive\xa\xa\xa{\xa\FX@numerator\xa}\xa{\FX@denominator}% +}% + +\def\FX@polynomialdivide@recursive#1#2{% + % #1 = f(x), of degree n + % #2 = g(x), of degree m + % Obtains a new polynomial h(x), congruent to f(x) modulo g(x), + % but of degree at most n-1. + % + % If leading coefficient of f(x) is 0, strips off that leading zero. + % If leading coefficient of f(x) is a, subtracts off a * g(x) * x^(n-m). + % N.B. we assume g is monic. + % + \FX@testleadingcoeff(#1)% + \ifFX@leadingcoeff@zero% + %Leading coefficient is zero, so remove it. + \xa\def\xa\FX@numerator\xa{\FX@stripleadingzero(#1)}% + \else% + %Leading coefficient is nonzero, and contained in \FX@leadingcoefficient + \FX@subtractphase{#1}{#2}{\FX@leadingcoefficient}% + \ifFX@subtract@failed% + %If subtraction failed, that means our #1 was already the remainder! + \FX@divisiondonetrue% + \edef\qr@theremainder{#1}% + \else% + %xor succeeded. We need to recurse. + \xa\xa\xa\edef\xa\xa\xa\FX@numerator\xa\xa\xa{\xa\FX@stripleadingzero\xa(\FX@subtraction@result)}% + \fi% + \fi% + \addtocounter{qr@divisionsremaining}{-1}% + \ifnum\c@qr@divisionsremaining=0\relax + %Division is done! + \FX@divisiondonetrue% + \edef\qr@theremainder{\FX@numerator}% + \relax% + \else% + \xa\FX@polynomialdivide@recursive\xa{\FX@numerator}{#2}% + \fi% +}% + +\def\FX@stripleadingzero(00#1){#1}%Strips off a single leading zero of F_256. + +\newif\ifFX@subtract@failed% This flag will trigger when #2 is longer than #1. + +\def\FX@subtractphase#1#2#3{% + % #1 = bitstring + % #2 = bitstring no longer than #1 + % #3 = leading coefficient + \FX@subtract@failedfalse% + \edef\qr@argument{(,#1\relax\relax\relax)(#2\relax\relax\relax)(#3)}% + \xa\FX@subtract@recursive\qr@argument% +}% + +\def\FX@subtract@recursive(#1,#2#3#4)(#5#6#7)(#8){% + % This is a recursive way to compute f(x) - a*g(x)*x^k. + % #1#2#3#4 is the first bitstring, subtracted up through #1. + % Thus #2#3 constitutes the next two-character coefficient. + % #5#6#7 is the remaining portion of the second bitstring. + % Thus #5#6 constitutes the next two-character coefficient + % #8 is the element a of F_256. It should contain two characters. + \def\qr@testii{#2}% + \def\qr@testv{#5}% + \ifx\qr@testii\qr@relax + % #1 contains the whole string. + % Now if #5 is also \relax, that means the two strings started off with equal lengths. + % If, however, #5 is not \relax, that means the second string was longer than the first, a problem. + \ifx\qr@testv\qr@relax + %No problem. We are done. + \FX@subtract@saveresult(#1#2#3#4)% %We keep the #2#3#4 to be sure we have all three relax-es to strip off. + \else + %Problem! The second string was longer than the first. + %This usually indicates the end of the long division process. + \FX@subtract@failedtrue + \def\FX@subtraction@result{}% + \fi + \else + % There is still a coefficient to manipulate in #2#3. + % Check whether #5 contains anything. + \ifx\qr@testv\qr@relax + % No, #5 is empty. We are done. "#2#3#4" contains the remainder of the first string, + % which we append untouched and then strip off the three \relax-es. + \FX@subtract@saveresult(#1#2#3#4)% + \else + % Yes, #5#6 still has something to XOR. Do the task. + \F@multiply{#5#6}{#8}% Multiply by the factor 'a'. + \F@addstrings{#2#3}{\F@result}% Subtract. (We're in characteristic two, so adding works.) + \edef\qr@argument{(#1\F@result,#4)(#7)(#8)}% + \xa\FX@subtract@recursive\qr@argument% + \fi + \fi +}% + +\def\FX@subtract@saveresult(#1\relax\relax\relax){% + %Strips off the three extra '\relax'es at the end. + \def\FX@subtraction@result{#1}% +}% + +\def\FX@creategeneratorpolynomial#1{% + % #1 = n, the number of error codewords desired. + % We need to create \prod_{j=0}^{n-1} (x-2^j). + \edef\FX@generator@degree{#1}% + \def\FX@generatorpolynomial{01}% Initially, set it equal to 1. + \setcounter{qr@i}{0}% + \FX@creategenerator@recursive% + %The result is now stored in \FX@generatorpolynomial +}% + +\def\FX@creategenerator@recursive{% + % \c@qr@i contains the current value of i. + % \FX@generatorpolynomial contains the current polynomial f(x), + % which should be a degree-i polynomial + % equal to \prod_{j=0}^{i-1} (x-2^j). + % (If i=0, then \FX@generatorpolynomial should be 01.) + % This recursion step should multiply the existing polynomial by (x-2^i), + % increment i by 1, and check whether we're done or not. + \edef\qr@summandA{\FX@generatorpolynomial 00}% This is f(x) * x + \edef\qr@summandB{00\FX@generatorpolynomial}% This is f(x), with a 0x^{i+1} in front. + \F@twotothe{\theqr@i}% + \edef\qr@theconstant{\F@result}% + \FX@subtractphase{\qr@summandA}{\qr@summandB}{\qr@theconstant}% + %This calculates \qr@summandA + \qr@theconstant * \qr@summandB + %and stores the result in \FX@subtraction@result + \edef\FX@generatorpolynomial{\FX@subtraction@result}% + \stepcounter{qr@i}% + \xa\ifnum\FX@generator@degree=\c@qr@i\relax% + %We just multiplied by (x-2^{n-1}), so we're done. + \relax% + \else% + %We need to do this again! + \xa% + \FX@creategenerator@recursive% + \fi% +}% + +\def\FX@generate@errorbytes#1#2{% + % #1 = datastream in hex + % #2 = number of error correction bytes requested + \edef\qr@numerrorbytes{#2}% + \xa\FX@creategeneratorpolynomial\xa{\qr@numerrorbytes}% + \edef\FX@numerator{#1}% + \qr@for \i = 1 to \qr@numerrorbytes by 1% + {\g@addto@macro\FX@numerator{00}}% %One error byte means two hex codes. + \FX@polynomialdivide{\FX@numerator}{\FX@generatorpolynomial}% + \edef\FX@errorbytes{\qr@theremainder}% +}% +% \end{macrocode} +% +% \subsection{Version handling} +% \begin{macrocode} +\newif\ifqr@versionmodules + +\def\qr@level@char#1{% + \xa\ifcase#1 + M\or L\or H\or Q\fi}% + +\newif\ifqr@versiongoodenough +\def\qr@choose@best@version#1{% + % \qr@desiredversion = user-requested version + % \qr@desiredlevel = user-requested error-correction level + \edef\qr@plaintext{#1}% + \qr@getstringlength{\qr@plaintext}% + % + %Run double loop over levels and versions, looking for + %the smallest version that can contain our data, + %and then choosing the best error-correcting level at that version, + %subject to the level being at least as good as the user desires. + \global\qr@versiongoodenoughfalse% + \gdef\qr@bestversion{0}% + \gdef\qr@bestlevel{0}% + \ifnum\qr@desiredversion=0\relax + \qr@a=1\relax + \else + \qr@a=\qr@desiredversion\relax + \fi + \qr@for \i=\qr@a to 40 by 1 + {\edef\qr@version{\the\i}% + \global\qr@versiongoodenoughfalse + \qr@for \j=0 to 3 by 1% + {%First, we map {0,1,2,3} to {1,0,4,3}, so that we loop through {M,L,H,Q} + %in order of increasing error-correction capabilities. + \qr@a = \j\relax + \divide \qr@a by 2\relax + \multiply \qr@a by 4\relax + \advance \qr@a by 1\relax + \advance \qr@a by -\j\relax + \edef\qr@level{\the\qr@a}% + \ifnum\qr@desiredlevel=\qr@a\relax + \global\qr@versiongoodenoughtrue + \fi + \ifqr@versiongoodenough + \qr@calculate@capacity{\qr@version}{\qr@level}% + \xa\xa\xa\ifnum\xa\qr@truecapacity\xa<\qr@stringlength\relax + %Too short + \relax + \else + %Long enough! + \xdef\qr@bestversion{\qr@version}% + \xdef\qr@bestlevel{\qr@level}% + \global\i=40% + \fi + \fi + }% + }% + \edef\qr@version{\qr@bestversion}% + \edef\qr@level{\qr@bestlevel}% + \xa\ifnum\qr@desiredversion>0\relax + \ifx\qr@bestversion\qr@desiredversion\relax + %No change from desired version. + \else + %Version was increased + \message{^^J}% + \fi + \fi + \ifx\qr@bestlevel\qr@desiredlevel\relax + %No change in level. + \else + \message{^^J}% + \fi +}% + +\def\qr@calculate@capacity#1#2{% + \edef\qr@version{#1}% + \edef\qr@level{#2}% + %Calculate \qr@size, the number of modules per side. + % The formula is 4\qr@version+17. + \qr@a=\qr@version\relax% + \multiply\qr@a by 4\relax% + \advance\qr@a by 17\relax% + \edef\qr@size{\the\qr@a}% + % + % Calculate \qr@k, which governs the number of alignment patterns. + % The alignment patterns lie in a kxk square, except for 3 that are replaced by finding patterns. + % The formula is 2 + floor( \qr@version / 7 ), except that k=0 for version 1. + \xa\ifnum\qr@version=1\relax% + \def\qr@k{0}% + \else% + \qr@a=\qr@version\relax + \divide \qr@a by 7\relax + \advance\qr@a by 2\relax + \edef\qr@k{\the\qr@a}% + \fi% + % + %Calculate number of function pattern modules. + %This consists of the three 8x8 finder patterns, the two timing strips, and the (k^2-3) 5x5 alignment patterns. + %The formula is 160+2n+25(k^2-3)-10(k-2), unless k=0 in which case we just have 160+2n. + \qr@a=\qr@size\relax + \multiply\qr@a by 2\relax + \advance\qr@a by 160\relax + \xa\ifnum\qr@k=0\relax\else + %\qr@k is nonzero, hence at least 2, so we continue to add 25(k^2-3)-10(k-2). + \qr@b=\qr@k\relax + \multiply\qr@b by \qr@k\relax + \advance\qr@b by -3\relax + \multiply\qr@b by 25\relax + \advance\qr@a by \qr@b\relax + \qr@b=\qr@k\relax + \advance\qr@b by -2\relax + \multiply\qr@b by 10\relax + \advance\qr@a by -\qr@b\relax + \fi + \edef\qr@numfunctionpatternmodules{\the\qr@a}% + % + %Calculate the number of version modules, either 36 or 0. + \xa\ifnum\qr@version>6\relax + \qr@versionmodulestrue + \def\qr@numversionmodules{36}% + \else + \qr@versionmodulesfalse + \def\qr@numversionmodules{0}% + \fi + % + %Now calculate the codeword capacity and remainder bits. + %Take n^2 modules, subtract all those dedicated to finder patterns etc., format information, and version information, + %and what's left is the number of bits we can play with. + %The number of complete bytes is \qr@numdatacodewords; + %the leftover bits are \qr@numremainderbits. + \qr@a=\qr@size\relax + \multiply \qr@a by \qr@size\relax + \advance \qr@a by -\qr@numfunctionpatternmodules\relax + \advance \qr@a by -31\relax% % There are 31 format modules. + \advance \qr@a by -\qr@numversionmodules\relax + \qr@b=\qr@a\relax + \divide \qr@a by 8\relax + \edef\qr@numdatacodewords{\the\qr@a}% + \multiply\qr@a by 8\relax + \advance \qr@b by -\qr@a\relax + \edef\qr@numremainderbits{\the\qr@b}% + % + %The size of the character count indicator also varies by version. + %There are only two options, so hardcoding seems easier than expressing these functionally. + \xa\ifnum\qr@version<10\relax + \def\qr@charactercountbytes@byte{1}% + \def\qr@charactercountbits@byte{8}% + \else + \def\qr@charactercountbytes@byte{2}% + \def\qr@charactercountbits@byte{16}% + \fi + % + %Now we call on the table, from the QR specification, + %of how many blocks to divide the message into, and how many error bytes each block gets. + %This affects the true capacity for data, which we store into \qr@totaldatacodewords. + % The following macro sets \qr@numblocks and \qr@num@eccodewords + % based on Table 9 of the QR specification. + \qr@settableix + \qr@a = -\qr@numblocks\relax + \multiply \qr@a by \qr@num@eccodewords\relax + \advance\qr@a by \qr@numdatacodewords\relax + \edef\qr@totaldatacodewords{\the\qr@a}% + \advance\qr@a by -\qr@charactercountbytes@byte\relax%Subtract character count + \advance\qr@a by -1\relax% Subtract 1 byte for the 4-bit mode indicator and the 4-bit terminator at the end. + \edef\qr@truecapacity{\the\qr@a}% +} + + +\def\qr@setversion#1#2{% + % #1 = version number, an integer between 1 and 40 inclusive. + % #2 = error-correction level, as an integer between 0 and 3 inclusive. + % 0 = 00 = M + % 1 = 01 = L + % 2 = 10 = H + % 3 = 11 = Q + % This macro calculates and sets a variety of global macros and/or counters + % storing version information that is used later in construction the QR code. + % Thus \qr@setversion should be called every time! + % + \edef\qr@version{#1}% + \edef\qr@level{#2}% + % + \qr@calculate@capacity{\qr@version}{\qr@level}% + %The capacity-check code sets the following: + % * \qr@size + % * \qr@k + % * \ifqr@versionmodules + % * \qr@numversionmodules + % * \qr@numdatacodewords + % * \qr@numremainderbits + % * \qr@charactercountbits@byte + % * \qr@charactercountbytes@byte + % * \qr@numblocks (via \qr@settableix) + % * \qr@num@eccodewords (via \qr@settableix) + % * \qr@totaldatacodewords + % + % The alignment patterns' square is 7 modules in from each edge. + % They are spaced "as evenly as possible" with an even number of modules between each row/column, + % unevenness in division being accommodated by making the first such gap smaller. + % The formula seems to be + % general distance = 2*round((n-13)/(k-1)/2+0.25) + % = 2*floor((n-13)/(k-1)/2+0.75) + % = 2*floor( (2*(n-13)/(k-1)+3) / 4 ) + % = (((2*(n-13)) div (k-1) + 3 ) div 4 ) * 2 + % first distance = leftovers + % The 0.25 is to accommodate version 32, which is the only time we round down. + % Otherwise a simple 2*ceiling((n-13)/(k-1)/2) would have sufficed. + % + \qr@a = \qr@size\relax + \advance\qr@a by -13\relax + \multiply\qr@a by 2\relax + \qr@b = \qr@k\relax + \advance \qr@b by -1\relax + \divide\qr@a by \qr@b\relax + \advance\qr@a by 3\relax + \divide\qr@a by 4\relax + \multiply\qr@a by 2\relax + \edef\qr@alignment@generalskip{\the\qr@a}% + % + %Now set \qr@alignment@firstskip to (\qr@size-13)-(\qr@k-2)*\qr@alignment@generalskip % + \qr@a = \qr@k\relax + \advance\qr@a by -2\relax + \multiply\qr@a by -\qr@alignment@generalskip\relax + \advance\qr@a by \qr@size\relax + \advance\qr@a by -13\relax + \edef\qr@alignment@firstskip{\the\qr@a}% + % + % + % + % Our \qr@totaldatacodewords bytes of data are broken up as evenly as possible + % into \qr@numblocks datablocks; some may be one byte longer than others. + % We set \qr@shortblock@size to floor(\qr@totaldatacodewords / \qr@numblocks) + % and \qr@numlongblocks to mod(\qr@totaldatacodewords , \qr@numblocks). + \qr@a=\qr@totaldatacodewords\relax + \divide\qr@a by \qr@numblocks\relax + \edef\qr@shortblock@size{\the\qr@a}% + \multiply\qr@a by -\qr@numblocks\relax + \advance\qr@a by \qr@totaldatacodewords\relax + \edef\qr@numlongblocks{\the\qr@a}% + % + %Set \qr@longblock@size to \qr@shortblock@size+1. + \qr@a=\qr@shortblock@size\relax + \advance\qr@a by 1\relax + \edef\qr@longblock@size{\the\qr@a}% + % + %Set \qr@numshortblocks to \qr@numblocks - \qr@numlongblocks + \qr@b=\qr@numblocks\relax + \advance\qr@b by -\qr@numlongblocks\relax + \edef\qr@numshortblocks{\the\qr@b}% +}% + +\def\qr@settableix@int(#1,#2){% + \edef\qr@numblocks{#1}% + \edef\qr@num@eccodewords{#2}% +}% + +\def\qr@settableix{% +\xa\ifcase\qr@level\relax + %00: Level 'M', medium error correction + \edef\qr@tempdata{(% + \ifcase\qr@version\relax + \relax %There is no version 0. + \or1,10% + \or1,16% + \or1,26% + \or2,18% + \or2,24% + \or4,16% + \or4,18% + \or4,22% + \or5,22% + \or5,26% + \or5,30% + \or8,22% + \or9,22% + \or9,24% + \or10,24% + \or10,28% + \or11,28% + \or13,26% + \or14,26% + \or16,26% + \or17,26% + \or17,28% + \or18,28% + \or20,28% + \or21,28% + \or23,28% + \or25,28% + \or26,28% + \or28,28% + \or29,28% + \or31,28% + \or33,28% + \or35,28% + \or37,28% + \or38,28% + \or40,28% + \or43,28% + \or45,28% + \or47,28% + \or49,28% + \fi)}% +\or + %01: Level 'L', low error correction + \edef\qr@tempdata{% + (\ifcase\qr@version\relax + \relax %There is no version 0. + \or 1,7% + \or 1,10% + \or 1,15% + \or 1,20% + \or 1,26% + \or 2,18% + \or 2,20% + \or 2,24% + \or 2,30% + \or 4,18% + \or 4,20% + \or 4,24% + \or 4,26% + \or 4,30% + \or 6,22% + \or 6,24% + \or 6,28% + \or 6,30% + \or 7,28% + \or 8,28% + \or 8,28% + \or 9,28% + \or 9,30% + \or 10,30% + \or 12,26% + \or 12,28% + \or 12,30% + \or 13,30% + \or 14,30% + \or 15,30% + \or 16,30% + \or 17,30% + \or 18,30% + \or 19,30% + \or 19,30% + \or 20,30% + \or 21,30% + \or 22,30% + \or 24,30% + \or 25,30% + \fi)}% +\or + %10: Level 'H', high error correction + \edef\qr@tempdata{(% + \ifcase\qr@version\relax + \relax %There is no version 0. + \or1,17% + \or1,28% + \or2,22% + \or4,16% + \or4,22% + \or4,28% + \or5,26% + \or6,26% + \or8,24% + \or8,28% + \or11,24% + \or11,28% + \or16,22% + \or16,24% + \or18,24% + \or16,30% + \or19,28% + \or21,28% + \or25,26% + \or25,28% + \or25,30% + \or34,24% + \or30,30% + \or32,30% + \or35,30% + \or37,30% + \or40,30% + \or42,30% + \or45,30% + \or48,30% + \or51,30% + \or54,30% + \or57,30% + \or60,30% + \or63,30% + \or66,30% + \or70,30% + \or74,30% + \or77,30% + \or81,30% + \fi)}% +\or + %11: Level 'Q', quality error correction + \edef\qr@tempdata{(% + \ifcase\qr@version\relax + \relax %There is no version 0. + \or1,13% + \or1,22% + \or2,18% + \or2,26% + \or4,18% + \or4,24% + \or6,18% + \or6,22% + \or8,20% + \or8,24% + \or8,28% + \or10,26% + \or12,24% + \or16,20% + \or12,30% + \or17,24% + \or16,28% + \or18,28% + \or21,26% + \or20,30% + \or23,28% + \or23,30% + \or25,30% + \or27,30% + \or29,30% + \or34,28% + \or34,30% + \or35,30% + \or38,30% + \or40,30% + \or43,30% + \or45,30% + \or48,30% + \or51,30% + \or53,30% + \or56,30% + \or59,30% + \or62,30% + \or65,30% + \or68,30% + \fi)}% +\fi +\xa\qr@settableix@int\qr@tempdata +}% +% \end{macrocode} +% \subsection{More key handling} +% \begin{macrocode} +\define@key{qr}{version}{\edef\qr@desiredversion{#1}}% +\define@key{qr}{level}{\qr@setlevel{#1}}% +\define@key{qr}{height}{\qr@setheight{#1}}% +\define@boolkey{qr}[qr@]{tight}[true]{}% %This creates \ifqr@tight and initializes it to true. +\define@boolkey{qr}[qr@]{padding}[true]{\ifqr@padding\qr@tightfalse\else\qr@tighttrue\fi}% %Define 'padding' as antonym to 'tight' + +\def\@qr@M{M}\def\@qr@z{0}% +\def\@qr@L{L}\def\@qr@i{1}% +\def\@qr@H{H}\def\@qr@ii{2}% +\def\@qr@Q{Q}\def\@qr@iii{3}% +\def\qr@setlevel#1{% + \edef\qr@level@selected{#1}% + \ifx\qr@level@selected\@qr@M + \edef\qr@desiredlevel{0}% + \fi + \ifx\qr@level@selected\@qr@L + \edef\qr@desiredlevel{1}% + \fi + \ifx\qr@level@selected\@qr@H + \edef\qr@desiredlevel{2}% + \fi + \ifx\qr@level@selected\@qr@Q + \edef\qr@desiredlevel{3}% + \fi + \ifx\qr@level@selected\@qr@z + \edef\qr@desiredlevel{0}% + \fi + \ifx\qr@level@selected\@qr@i + \edef\qr@desiredlevel{1}% + \fi + \ifx\qr@level@selected\@qr@ii + \edef\qr@desiredlevel{2}% + \fi + \ifx\qr@level@selected\@qr@iii + \edef\qr@desiredlevel{3}% + \fi +}% + +\def\qr@setheight#1{% + \setlength{\qr@desiredheight}{#1}% +}% + +\newcommand\qrset[1]{% + \setkeys{qr}{#1}% +} + +%SET DEFAULTS +\qrset{version=0, level=0, tight} +% \end{macrocode} +% \subsection{Main user functions} +% At last we are ready to define the main user functions. +% Some care is needed to ensure +% that the \meta{text to be encoded} is read with the appropriate catcodes, +% and that any escaped special characters are converted to the intended +% characters with category code 12 (other). +% \begin{macrocode} +\newif\ifqr@starinvoked% +\def\qrcode{\@ifstar\qrcode@star\qrcode@nostar}% +\def\qrcode@star{\qr@starinvokedtrue\qrcode@i}% +\def\qrcode@nostar{\qr@starinvokedfalse\qrcode@i}% + +\newcommand\qrcode@i[1][]{% + \begingroup% + \ifqr@starinvoked% + \qr@hyperlinkfalse% + \fi% + \setkeys{qr}{#1}% + \bgroup\qr@verbatimcatcodes\qr@setescapedspecials\qrcode@in}% + +\def\qrcode@in#1{\xdef\qr@texttoencode{#1}\egroup\qrcode@int\endgroup}% + +\def\qrcode@hyperwrapper@hyperref{\href{\qr@texttoencode}}% +\def\qrcode@hyperwrapper@nohyperref{\relax}% + +\AtBeginDocument{% + \@ifpackageloaded{hyperref}% + {\global\let\qrcode@hyperwrapper=\qrcode@hyperwrapper@hyperref}% + {\global\let\qrcode@hyperwrapper=\qrcode@hyperwrapper@nohyperref}% +}% + +\def\qrcode@int{% + \message{^^J^^J^^J}% + %First, choose the version and level. + %Recall that \qr@choose@best@version sets \qr@version and \qr@level. + \xa\qr@choose@best@version\xa{\qr@texttoencode}% + \qr@setversion{\qr@version}{\qr@level}% + % + \ifqr@hyperlink% + \let\qrcode@wrapper=\qrcode@hyperwrapper% + \else% + \let\qrcode@wrapper=\relax% + \fi% + % + %Next, check whether we have already encoded this text at this version + %and level. + \qrcode@wrapper{% + \xa\ifx\csname qr@savedbinarymatrix@\qr@texttoencode @\qr@version @\qr@level\endcsname + \relax% + %This text has not yet been encoded. + \qrcode@int@new% + \else + %This text has already been encoded! + \ifqr@forget@mode + %In 'forget' mode, we deliberately recalculate anyway. + \qrcode@int@new% + \else + \qrcode@int@remember% + \fi + \fi% + }% +}% + +\def\qrcode@int@new{% + \qr@createsquareblankmatrix{newqr}{\qr@size}% + \qr@placefinderpatterns{newqr}% + \qr@placetimingpatterns{newqr}% + \qr@placealignmentpatterns{newqr}% + \qr@placedummyformatpatterns{newqr}% + \qr@placedummyversionpatterns{newqr}% + \ifqr@draft@mode + \message{^^J}% + \relax% Draft mode---don't load any data or do any work. Also don't save! + \def\qr@format@square{\qr@black}% + \def\qr@blank{\qr@white}% + \fboxsep=-\fboxrule% + \fbox{\qr@printmatrix{newqr}}% + \else + \message{^^J}% + \xa\qr@encode@binary\xa{\qr@texttoencode}% + \qr@splitcodetextintoblocks + \qr@createerrorblocks + \qr@interleave + \message{^^J}% + \qr@writeremainderbits{newqr}% + \qr@chooseandapplybestmask{newqr}% + \qr@decimaltobinary[2]{\qr@level@binary}{\qr@level}% + \qr@decimaltobinary[3]{\qr@mask@binary}{\qr@mask@selected}% + \edef\qr@formatstring{\qr@level@binary\qr@mask@binary}% + \message{^^J}% + \message{^^J}% + \message{^^J}% + % + %Also save the binary version into the aux file, for use in later runs. + \message{^^J}% + \message{^^J}% + \fi + \message{^^J}% +}% +\def\qrcode@int@remember{% + %This text has already been encoded, + %so we just copy it from the saved binary string. + \message{^^J}% + \xa\qr@printsavedbinarymatrix\xa{\csname qr@savedbinarymatrix@\qr@texttoencode @\qr@version @\qr@level\endcsname}% + % + % Now this still might need to be written to the aux file. + % + \xa\ifx\csname qr@savedflag@\qr@texttoencode @\qr@version @\qr@level\endcsname\@qr@TRUE + %Okay, this has already been written to aux file. + %Do nothing. + \relax% + \else% + %This has NOT been written to the aux file yet. + %We need to do so now. + \xa\qr@writebinarymatrixtoauxfile\xa{\csname qr@savedbinarymatrix@\qr@texttoencode @\qr@version @\qr@level\endcsname}% + \fi% +}% + +\def\qr@matrixtobinary#1{% + \def\qr@binarymatrix@result{}% + \bgroup + \def\qr@black{1}% + \def\qr@white{0}% + \def\qr@blank{0}% + \def\qr@black@fixed{1}% + \def\qr@white@fixed{0}% + \def\qr@black@format{1}% + \def\qr@white@format{0}% + % + \qr@for \i = 1 to \qr@size by 1% + {\qr@for \j = 1 to \qr@size by 1% + {\edef\qr@theentry{\qr@matrixentry{#1}{\the\i}{\the\j}}% + \xa\g@addto@macro\xa\qr@binarymatrix@result\xa{\qr@theentry}% + }% + }% + \egroup% +}% + +\def\qr@sanitize@output#1{% + %Read through ASCII text '#1' and escape backslashes and braces + \def\qr@sanitized@result{}% + \edef\qr@argument{(#1\relax\relax\relax)}% + \xa\qr@sanitize@output@int\qr@argument% +} + +\def\qr@sanitize@output@int(#1#2){% + % #1 = first character + % #2 = rest of output, including terminator + \edef\qr@testi{#1}% + \ifx\qr@testi\qr@relax + % Done. + \let\qr@next=\relax + \else + \ifx\qr@testi\qr@otherrightbrace + \edef\qr@sanitized@result{\qr@sanitized@result\qr@otherbackslash}% + \else\ifx\qr@testi\qr@otherleftbrace + \edef\qr@sanitized@result{\qr@sanitized@result\qr@otherbackslash}% + \else\ifx\qr@testi\qr@otherbackslash + \edef\qr@sanitized@result{\qr@sanitized@result\qr@otherbackslash}% + \fi + \fi + \fi + \edef\qr@sanitized@result{\qr@sanitized@result#1}% + \def\qr@next{\qr@sanitize@output@int(#2)}% + \fi + \qr@next +} + +\def\@qr@TRUE{TRUE}% +\def\qr@writebinarymatrixtoauxfile#1{% + \qr@sanitize@output{\qr@texttoencode}% + \edef\qr@theargument{{\qr@sanitized@result}{\qr@version}{\qr@level}{#1}}% + \xa\write\xa\@auxout\xa{\xa\string\xa\qr@savematrix\qr@theargument}% + % + % Now set a flag, so we don't write this again. + \xa\gdef\csname qr@savedflag@\qr@texttoencode @\qr@version @\qr@level\endcsname{TRUE}% +}% + +\gdef\qr@dummyqrsavedefinition{}% +\begingroup + \catcode`\#=12\relax + \catcode`\<=1\relax + \catcode`\{=12\relax + \catcode`\>=2\relax + \catcode`\}=12\relax + \catcode`\|=0\relax + \catcode`\\=12|relax + |gdef|qr@dummyqrsavedefinition<% + \ifx\qr@savematrix\@undefined% + \def\qr@savematrix{\begingroup\let\do\@makeother\dospecials\catcode`\{=1\catcode`\}=2\relax + \qr@savematrix@int}% + \def\qr@savematrix@int#1#2#3#4{\endgroup}% + \fi% + > +|endgroup + +\edef\qr@argument{(\qr@dummyqrsavedefinition)}% +\xa\write\xa\@auxout\xa{\qr@dummyqrsavedefinition}% + +\def\qr@savematrix{\bgroup\qr@verbatimcatcodes\qr@setescapedspecials\qr@savematrix@int}% + +\def\qr@savematrix@int#1{\xdef\qr@savedmatrix@name{#1}\egroup\qr@savematrix@int@int}% + +\def\qr@savematrix@int@int#1#2#3{% + % \qr@savedmatrix@name = encoded text + % #1 = version + % #2 = level + % #3 = binary text + \def\ds{^^J}\xa\message\xa{\ds}% + {\let\%=\qr@otherpercent + \xa\gdef\csname qr@savedbinarymatrix@\qr@savedmatrix@name @#1@#2\endcsname{#3}% + }% +}% +% \end{macrocode} +% +% \Finale +\endinput diff --git a/tools/style/qrcode.ins b/tools/style/qrcode.ins new file mode 100644 index 0000000..6e5eade --- /dev/null +++ b/tools/style/qrcode.ins @@ -0,0 +1,57 @@ +%% qrcode.ins +%% Copyright 2015 by Anders O.F. Hendrickson +%% +%% 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 Anders O.F. Hendrickson. +%% +%% This work consists of the files qrcode.dtx and qrcode.ins +%% and the derived file qrcode.sty. + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/qrcode} + +\preamble + +This is a generated file. + +Copyright (C) 2015 by Anders Hendrickson + +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. + +\endpreamble + +\generate{\file{qrcode.sty}{\from{qrcode.dtx}{package}}} + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* qrcode.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file qrcode.dtx *} +\Msg{* through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile diff --git a/tools/style/qrcode.sty b/tools/style/qrcode.sty new file mode 100644 index 0000000..6330464 --- /dev/null +++ b/tools/style/qrcode.sty @@ -0,0 +1,3051 @@ +%% +%% This is file `qrcode.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% qrcode.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% Copyright (C) 2015 by Anders Hendrickson +%% +%% 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. +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{qrcode} + [2015/01/08 v1.51 QR code generation] +%%PACKAGE LOADING +\RequirePackage{xcolor}% +\RequirePackage{xkeyval}% + +%%INITIAL CODE +\newif\ifqr@draft@mode +\newif\ifqr@forget@mode + +%%DECLARATION OF OPTIONS +\define@boolkey{qr}[qr@]{draft}[true]{\ifqr@draft\qr@draft@modetrue\else\qr@draft@modefalse\fi}% +\define@boolkey{qr}[qr@]{final}[true]{\ifqr@final\qr@draft@modefalse\else\qr@draft@modetrue\fi}% +\define@boolkey{qr}[qr@]{forget}[true]{\ifqr@forget\qr@forget@modetrue\else\qr@forget@modefalse\fi}% +\define@boolkey{qr}[qr@]{hyperlink}[true]{}% %This creates \ifqr@hyperlink. +\define@boolkey{qr}[qr@]{hyperlinks}[true]{\ifqr@hyperlinks\qr@hyperlinktrue\else\qr@hyperlinkfalse\fi}% +\define@boolkey{qr}[qr@]{link}[true]{\ifqr@link\qr@hyperlinktrue\else\qr@hyperlinkfalse\fi}% +\define@boolkey{qr}[qr@]{nolink}[true]{\ifqr@nolink\qr@hyperlinkfalse\else\qr@hyperlinktrue\fi}% %Make nolink an antonym. +\define@boolkey{qr}[qr@]{links}[true]{\ifqr@links\qr@hyperlinktrue\else\qr@hyperlinkfalse\fi}% +\define@boolkey{qr}[qr@]{nolinks}[true]{\ifqr@nolinks\qr@hyperlinkfalse\else\qr@hyperlinktrue\fi}% %Make nolinks an antonym. + +%%EXECUTION OF OPTIONS +\qr@draft@modefalse +\qr@forget@modefalse +\qr@hyperlinktrue + +\ProcessOptionsX + +\newcounter{qr@i}% +\newcounter{qr@j}% +\newcount\qr@a +\newcount\qr@b +\newcount\qr@c + +\let\xa=\expandafter + +\newlinechar=`\^^J + +\def\qr@relax{\relax}% + +\def\qr@preface@macro#1#2{% + % #1 = macro name + % #2 = text to add to front of macro + \def\qr@tempb{#2}% + \xa\xa\xa\def\xa\xa\xa#1\xa\xa\xa{\xa\qr@tempb #1}% +}% + +\def\qr@g@preface@macro#1#2{% + % #1 = macro to be appended to + % #2 = code to add + \edef\qr@tempb{#2}% + \xa\xa\xa\gdef\xa\xa\xa#1\xa\xa\xa{\xa\qr@tempb#1}% +} + +\def\qr@getstringlength#1{% + \bgroup + \qr@a=0% + \xdef\qr@thestring{#1}% + \xa\qr@stringlength@recursive\xa(\qr@thestring\relax\relax)% + \xdef\qr@stringlength{\the\qr@a}% + \egroup +}% + +\def\qr@stringlength@recursive(#1#2){% + \def\qr@testi{#1}% + \ifx\qr@testi\qr@relax + %we are done. + \let\qr@next=\relax% + \else + \advance\qr@a by 1% + \def\qr@next{\qr@stringlength@recursive(#2)}% + \fi + \qr@next +}% +\newcount\qr@for@depth% +\newcount\qr@for@maxdepth% +\qr@for@depth=0% +\qr@for@maxdepth=0% +\newcount\qr@for@start% +\newcount\qr@for@end% +\newcount\qr@for@step% +\def\qr@allocate@new@for@counter{% + \global\advance\qr@for@maxdepth by 1% + \newcount\qr@newforcount% + \xa\global\xa\let\csname qr@for@var@\the\qr@for@maxdepth\endcsname=\qr@newforcount% +}% + +\newif\ifqr@loopshouldrun +\def\qr@for #1=#2to#3by#4#{% + \qr@for@int{#1}{#2}{#3}{#4}% +}% +\long\def\qr@for@int#1#2#3#4#5{% + \bgroup + %Because we're working within a TeX group, + %any values of \qr@for@start, \qr@for@end, and \qr@for@step from an outer loop + %will be restored after the \egroup. + % + %For the \qr@for@var itself, however, we need a different counter, + %because the user's text within the loop might need to access the variable from the outer loop. + \advance\qr@for@depth by 1\relax% This is a local change. + \ifnum\qr@for@depth>\qr@for@maxdepth% + %This is the first time we have gone to this depth of nesting! + %We should only be over by one. + \qr@allocate@new@for@counter% + \fi + \xa\let\xa\qr@for@var\xa=\csname qr@for@var@\the\qr@for@depth\endcsname% + %Now \qr@for@var points to the same register as \qr@for@var@3 or something. + %The next line lets the user-level variable (e.g., \i or \j) point to the same count register. + \let#1=\qr@for@var% + %Now establish the looping parameters. + \edef\qr@for@start@text{#2}% + \edef\qr@for@end@text{#3}% + \edef\qr@for@step@text{#4}% + \def\qr@for@body{\bgroup #5\egroup}% + \xa\qr@for@start\qr@for@start@text\relax% + \xa\qr@for@end \qr@for@end@text\relax% + \xa\qr@for@step \qr@for@step@text\relax% + % + %Next, test whether the loop should run at all. + % * "\qr@for \i = 1 to 0 by 1" should fail. + % * "\qr@for \i = 3 to 5 by -1" should fail. + % * "\qr@for \i = 6 to 2 by 1" should fail. + % * "\qr@for \i = 4 to 4 by -1" should run. + % * "\qr@for \i = 4 to 4 by 1" should run. + % * "\qr@for \i = 5 to 7 by 0" should fail. + %The loop should fail if (step)=0 or if (step) and (end-start) have opposite signs. + %The loop will fail if (step=0) or (step)*(end-start)<0. + % TODO: "\qr@for \i = 5 to 5 by 0" should run (just one iteration). + \qr@loopshouldruntrue + \ifnum\qr@for@step=0\relax + \qr@loopshouldrunfalse + \fi + \qr@a=\qr@for@end% + \advance\qr@a by -\qr@for@start% + \multiply\qr@a by \qr@for@step% + \ifnum\qr@a<0\relax + \qr@loopshouldrunfalse + \fi + \ifqr@loopshouldrun + \qr@for@var=\qr@for@start% + \ifnum\qr@for@step>0\relax + \def\qr@for@recursive{% + \qr@for@body% + \advance\qr@for@var by \qr@for@step% + \ifnum\qr@for@var>\qr@for@end% + \let\qr@for@next=\relax% + \else% + \let\qr@for@next=\qr@for@recursive% + \fi% + \qr@for@next% + }% + \else + \def\qr@for@recursive{% + \qr@for@body% + \advance\qr@for@var by \qr@for@step% + \ifnum\qr@for@var<\qr@for@end% + \let\qr@for@next=\relax% + \else% + \let\qr@for@next=\qr@for@recursive% + \fi% + \qr@for@next% + }% + \fi + \qr@for@recursive% + \fi + \egroup +}% +\def\qr@padatfront#1#2{% + % #1 = macro containing text to pad + % #2 = desired number of characters + % Pads a number with initial zeros. + \qr@getstringlength{#1}% + \qr@a=\qr@stringlength\relax% + \advance\qr@a by 1\relax% + \qr@for \i = \qr@a to #2 by 1\relax% + {\qr@g@preface@macro{#1}{0}}% +} + +\qr@a=-1\relax% +\def\qr@savehexsymbols(#1#2){% + \advance\qr@a by 1\relax% + \xa\def\csname qr@hexchar@\the\qr@a\endcsname{#1}% + \xa\edef\csname qr@hextodecimal@#1\endcsname{\the\qr@a}% + \ifnum\qr@a=15\relax + %Done. + \let\qr@next=\relax% + \else + \def\qr@next{\qr@savehexsymbols(#2)}% + \fi% + \qr@next% +}% +\qr@savehexsymbols(0123456789abcdef\relax\relax)% + +\def\qr@decimaltobase#1#2#3{% + % #1 = macro to store result + % #2 = decimal representation of a positive integer + % #3 = new base + \bgroup + \edef\qr@newbase{#3}% + \gdef\qr@base@result{}% + \qr@a=#2\relax% + \qr@decimaltobase@recursive% + \xdef#1{\qr@base@result}% + \egroup +} +\def\qr@decimaltobase@recursive{% + \qr@b=\qr@a% + \divide\qr@b by \qr@newbase\relax + \multiply\qr@b by -\qr@newbase\relax + \advance\qr@b by \qr@a\relax% + \divide\qr@a by \qr@newbase\relax% + \ifnum\qr@b<10\relax + \edef\qr@newdigit{\the\qr@b}% + \else + \edef\qr@newdigit{\csname qr@hexchar@\the\qr@b\endcsname}% + \fi + \edef\qr@argument{{\noexpand\qr@base@result}{\qr@newdigit}}% + \xa\qr@g@preface@macro\qr@argument% + \ifnum\qr@a=0\relax + \relax + \else + \xa\qr@decimaltobase@recursive + \fi +} + +\newcommand\qr@decimaltohex[3][0]{% + % #1 (opt.) = number of hex digits to create + % #2 = macro to store result + % #3 = decimal digits to convert + \qr@decimaltobase{#2}{#3}{16}% + \qr@padatfront{#2}{#1}% +} + +\newcommand\qr@decimaltobinary[3][0]{% + % #1 (opt.) = number of bits to create + % #2 = macro to store result + % #3 = decimal digits to convert + \qr@decimaltobase{#2}{#3}{2}% + \qr@padatfront{#2}{#1}% +} + +\qr@for \i = 0 to 15 by 1% + {% + \qr@decimaltohex[1]{\qr@hexchar}{\the\i}% + \qr@decimaltobinary[4]{\qr@bits}{\the\i}% + \xa\xdef\csname qr@b2h@\qr@bits\endcsname{\qr@hexchar}% + \xa\xdef\csname qr@h2b@\qr@hexchar\endcsname{\qr@bits}% + }% + +\newcommand\qr@binarytohex[3][\relax]{% + % #1 (optional) = # digits desired + % #2 = macro to save to + % #3 = binary string (must be multiple of 4 bits) + \def\qr@test@i{#1}% + \ifx\qr@test@i\qr@relax% + %No argument specified + \def\qr@desireddigits{0}% + \else + \def\qr@desireddigits{#1}% + \fi + \gdef\qr@base@result{}% + \edef\qr@argument{(#3\relax\relax\relax\relax\relax)}% + \xa\qr@binarytohex@int\qr@argument% + \qr@padatfront{\qr@base@result}{\qr@desireddigits}% + \xdef#2{\qr@base@result}% +} +\def\qr@binarytohex@int(#1#2#3#4#5){% + % #1#2#3#4 = 4 bits + % #5 = remainder, including \relax\relax\relax\relax\relax terminator + \def\qr@test@i{#1}% + \ifx\qr@test@i\qr@relax% + %Done. + \def\qr@next{\relax}% + \else% + \xdef\qr@base@result{\qr@base@result\csname qr@b2h@#1#2#3#4\endcsname}% + \def\qr@next{\qr@binarytohex@int(#5)}% + \fi% + \qr@next% +} + +\newcommand\qr@hextobinary[3][\relax]{% + % #1 (optional) = # bits desired + % #2 = macro to save to + % #3 = hexadecimal string + \bgroup + \def\qr@test@i{#1}% + \ifx\qr@test@i\qr@relax% + %No argument specified + \def\qr@desireddigits{0}% + \else + \def\qr@desireddigits{#1}% + \fi + \gdef\qr@base@result{}% + \edef\qr@argument{(#3\relax\relax)}% + \xa\qr@hextobinary@int\qr@argument% + \qr@padatfront{\qr@base@result}{\qr@desireddigits}% + \xdef#2{\qr@base@result}% + \egroup +} +\def\qr@hextobinary@int(#1#2){% + % #1 = hexadecimal character + % #2 = remainder, including \relax\relax terminator + \def\qr@test@@i{#1}% + \ifx\qr@test@@i\qr@relax% + %Done. + \def\qr@next{\relax}% + \else% + \xdef\qr@base@result{\qr@base@result\csname qr@h2b@#1\endcsname}% + \def\qr@next{\qr@hextobinary@int(#2)}% + \fi% + \qr@next% +} + +\def\qr@hextodecimal#1#2{% + \edef\qr@argument{#2}% + \xa\qr@a\xa=\xa\number\xa"\qr@argument\relax% + \edef#1{\the\qr@a}% +} + +\def\qr@hextodecimal#1#2{% + % #1 = macro to store result + % #2 = hexadecimal representation of a positive integer + \bgroup + \qr@a=0\relax% + \edef\qr@argument{(#2\relax)}% + \xa\qr@hextodecimal@recursive\qr@argument% + \xdef#1{\the\qr@a}% + \egroup +} +\def\qr@hextodecimal@recursive(#1#2){% + % #1 = first hex char + % #2 = remainder + \advance \qr@a by \csname qr@hextodecimal@#1\endcsname\relax% + \edef\qr@testii{#2}% + \ifx\qr@testii\qr@relax% + %Done. + \let\qr@next=\relax% + \else + %There's at least one more digit. + \multiply\qr@a by 16\relax + \edef\qr@next{\noexpand\qr@hextodecimal@recursive(#2)}% + \fi% + \qr@next% +} +{\catcode`\ =12\relax\gdef\qr@otherspace{ }}% +{\catcode`\%=12\relax\gdef\qr@otherpercent{%}}% +{\catcode`\#=12\relax\gdef\qr@otherpound{#}}% +{\catcode`\|=0\relax|catcode`|\=12|relax|gdef|qr@otherbackslash{\}}% +{\catcode`\^^J=12\relax\gdef\qr@otherlf{^^J}}% +\bgroup + \catcode`\<=1\relax + \catcode`\>=2\relax + \catcode`\{=12\relax\gdef\qr@otherleftbrace<{>% + \catcode`\}=12\relax\gdef\qr@otherrightbrace<}>% +\egroup% +{\catcode`\&=12\relax\gdef\qr@otherampersand{&}}% +{\catcode`\~=12\relax\gdef\qr@othertilde{~}}% +{\catcode`\^=12\relax\gdef\qr@othercaret{^}}% +{\catcode`\_=12\relax\gdef\qr@otherunderscore{_}}% +{\catcode`\$=12\relax\gdef\qr@otherdollar{$}}% + +{\catcode`\^^M=13\relax\gdef\qr@verbatimlinefeeds{\let^^M=\qr@otherlf}} +\def\qr@verbatimcatcodes{% + \catcode`\#=12\relax + \catcode`\$=12\relax + \catcode`\&=12\relax + \catcode`\^=12\relax + \catcode`\_=12\relax + \catcode`\~=12\relax + \catcode`\%=12\relax + \catcode`\ =12\relax + \catcode`\^^M=13\relax\qr@verbatimlinefeeds}% + +\def\qr@setescapedspecials{% + \let\ =\qr@otherspace% + \let\%=\qr@otherpercent% + \let\#=\qr@otherpound% + \let\&=\qr@otherampersand% + \let\^=\qr@othercaret% + \let\_=\qr@otherunderscore% + \let\~=\qr@othertilde% + \let\$=\qr@otherdollar% + \let\\=\qr@otherbackslash% + \let\{=\qr@otherleftbrace% + \let\}=\qr@otherrightbrace% + \let\?=\qr@otherlf% +}% +\def\qr@creatematrix#1{% + \xa\gdef\csname #1\endcsname##1##2{% + \csname #1@##1@##2\endcsname + }% +}% + +\def\qr@storetomatrix#1#2#3#4{% + % #1 = matrix name + % #2 = row number + % #3 = column number + % #4 = value of matrix entry + \xa\gdef\csname #1@#2@#3\endcsname{#4}% +}% + +\def\qr@estoretomatrix#1#2#3#4{% + % This version performs exactly one expansion on #4. + % #1 = matrix name + % #2 = row number + % #3 = column number + % #4 = value of matrix + \xa\xa\xa\gdef\xa\xa\csname #1@#2@#3\endcsname\xa{#4}% +}% + +\def\qr@matrixentry#1#2#3{% + % #1 = matrix name + % #2 = row number + % #3 = column number + \csname #1@#2@#3\endcsname% +}% + +\def\qr@createsquareblankmatrix#1#2{% + \qr@creatematrix{#1}% + \xa\gdef\csname #1@numrows\endcsname{#2}% + \xa\gdef\csname #1@numcols\endcsname{#2}% + \qr@for \i = 1 to #2 by 1% + {\qr@for \j = 1 to #2 by 1% + {\qr@storetomatrix{#1}{\the\i}{\the\j}{\qr@blank}}}% +}% + +\def\qr@numberofrowsinmatrix#1{% + \csname #1@numrows\endcsname% +}% + +\def\qr@numberofcolsinmatrix#1{% + \csname #1@numcols\endcsname% +}% + +\def\qr@setnumberofrows#1#2{% + \xa\xdef\csname #1@numrows\endcsname{#2}% +}% + +\def\qr@setnumberofcols#1#2{% + \xa\xdef\csname #1@numcols\endcsname{#2}% +}% + +\newlength\qr@desiredheight +\setlength\qr@desiredheight{2cm}% +\newlength\qr@modulesize +\newlength\qr@minipagewidth + +\def\qr@printmatrix#1{% + \def\qr@black{\rule{\qr@modulesize}{\qr@modulesize}}% + \def\qr@white{\rule{\qr@modulesize}{0pt}}% + \def\qr@black@fixed{\rule{\qr@modulesize}{\qr@modulesize}}% + \def\qr@white@fixed{\rule{\qr@modulesize}{0pt}}% + \def\qr@black@format{\rule{\qr@modulesize}{\qr@modulesize}}% + \def\qr@white@format{\rule{\qr@modulesize}{0pt}}% + %Set module size + \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 + \begin{minipage}{\qr@minipagewidth}% + \baselineskip=\qr@modulesize% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% %Blank space at top. + \qr@for \i = 1 to \qr@numberofrowsinmatrix{#1} by 1% + {\ifqr@tight\else\rule{4\qr@modulesize}{0pt}\fi% %Blank space at left. + \qr@for \j = 1 to \qr@numberofcolsinmatrix{#1} by 1% + {\qr@matrixentry{#1}{\the\i}{\the\j}}% + \par}% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% + \end{minipage}% +}% + +\def\qr@printsavedbinarymatrix#1{% + \edef\qr@binarystring{#1\relax\relax}% + %Set module size + \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 + \begin{minipage}{\qr@minipagewidth}% + \baselineskip=\qr@modulesize% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% %Blank space at top. + \qr@for \i = 1 to \qr@size by 1% + {\ifqr@tight\else\rule{4\qr@modulesize}{0pt}\fi% %Blank space at left. + \qr@for \j = 1 to \qr@size by 1% + {\edef\qr@theargument{(\qr@binarystring)}% + \xa\qr@printsavedbinarymatrix@int\qr@theargument + }% + \par}% + \ifqr@tight\else\rule{0pt}{4\qr@modulesize}\par\fi% + \end{minipage}% +}% + +\def\qr@printsavedbinarymatrix@int(#1#2){% + % #1 = first bit, either 1 or 0. + % #2 = remainder of string, terminating with \relax\relax + % There's no need to check for EOF here, because + % we'll only call this n^2 times. + \ifcase #1\relax + \rule{\qr@modulesize}{0pt}% % 0: white square + \or + \rule{\qr@modulesize}{\qr@modulesize}% % 1: black square + \fi + \xdef\qr@binarystring{#2}% +}% + +\def\qr@createliteralmatrix#1#2#3{% + % #1 = matrix name + % #2 = m, the number of rows and columns in the square matrix + % #3 = a string of m^2 tokens to be written into the matrix + \qr@creatematrix{#1}% + \xa\xdef\csname #1@numrows\endcsname{#2}% + \xa\xdef\csname #1@numcols\endcsname{#2}% + \gdef\qr@literalmatrix@tokens{#3}% + \qr@for \i = 1 to #2 by 1% + {\qr@for \j = 1 to #2 by 1% + {\xa\qr@createliteralmatrix@int\xa(\qr@literalmatrix@tokens)% + \qr@estoretomatrix{#1}{\the\i}{\the\j}{\qr@entrytext}% + }% + }% +} +\def\qr@createliteralmatrix@int(#1#2){% + \def\qr@entrytext{#1}% + \gdef\qr@literalmatrix@tokens{#2}% +} + +\qr@createliteralmatrix{finderpattern}{8}{% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@white@fixed% + \qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed% +}% + +\qr@createliteralmatrix{alignmentpattern}{5}{% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed% + \qr@black@fixed\qr@white@fixed\qr@black@fixed\qr@white@fixed\qr@black@fixed% + \qr@black@fixed\qr@white@fixed\qr@white@fixed\qr@white@fixed\qr@black@fixed% + \qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed\qr@black@fixed% +}% + +\def\qr@copymatrixentry#1#2#3#4#5#6{% + % Copy the (#2,#3) entry of matrix #1 + % to the (#5,#6) position of matrix #4. + \xa\xa\xa\global% + \xa\xa\xa\let\xa\xa\csname #4@#5@#6\endcsname% + \csname #1@#2@#3\endcsname% +}% + +\def\qr@createduplicatematrix#1#2{% + % #1 = name of copy + % #2 = original matrix to be copied + \qr@creatematrix{#1}% + \qr@for \i = 1 to \qr@numberofrowsinmatrix{#2} by 1% + {\qr@for \j = 1 to \qr@numberofcolsinmatrix{#2} by 1% + {\qr@copymatrixentry{#2}{\the\i}{\the\j}{#1}{\the\i}{\the\j}% + }% + }% + \qr@setnumberofrows{#1}{\qr@numberofrowsinmatrix{#2}}% + \qr@setnumberofcols{#1}{\qr@numberofcolsinmatrix{#2}}% +}% + +\def\qr@placefinderpattern@int#1#2#3#4#5{% + % Work on matrix #1. + % Start in position (#2, #3) -- should be a corner + % #4 indicates horizontal direction (1=right, -1=left) + % #5 indicates vertical direction (1=down, -1=up) + % + % In this code, \sourcei and \sourcej are TeX counts working through the finderpattern matrix, + % and i and j are LaTeX counters indicating positions in the big matrix. + \setcounter{qr@i}{#2}% + \qr@for \sourcei=1 to 8 by 1% + {\setcounter{qr@j}{#3}% + \qr@for \sourcej=1 to 8 by 1% + {\qr@copymatrixentry{finderpattern}{\the\sourcei}{\the\sourcej}% + {#1}{\theqr@i}{\theqr@j}% + \addtocounter{qr@j}{#5}% + }% + \addtocounter{qr@i}{#4}% + }% +}% + +\def\qr@placefinderpatterns#1{% + % #1=matrix name + \qr@placefinderpattern@int{#1}{1}{1}{1}{1}% + \qr@placefinderpattern@int{#1}{\qr@numberofrowsinmatrix{#1}}{1}{-1}{1}% + \qr@placefinderpattern@int{#1}{1}{\qr@numberofcolsinmatrix{#1}}{1}{-1}% +}% + +\def\qr@placetimingpatterns#1{% + %Set \qr@endingcol to n-8. + \qr@a=\qr@size\relax% + \advance\qr@a by -8\relax% + \edef\qr@endingcol{\the\qr@a}% + \qr@for \j = 9 to \qr@endingcol by 1% + {\ifodd\j\relax% + \qr@storetomatrix{#1}{7}{\the\j}{\qr@black@fixed}% + \qr@storetomatrix{#1}{\the\j}{7}{\qr@black@fixed}% + \else% + \qr@storetomatrix{#1}{7}{\the\j}{\qr@white@fixed}% + \qr@storetomatrix{#1}{\the\j}{7}{\qr@white@fixed}% + \fi% + }% +}% + +\def\qr@placealignmentpattern@int#1#2#3{% + % Work on matrix #1. + % Write an alignment pattern into the matrix, centered on (#2,#3). + \qr@a=#2\relax% + \advance\qr@a by -2\relax% + \qr@b=#3\relax% + \advance\qr@b by -2\relax% + \setcounter{qr@i}{\the\qr@a}% + \qr@for \i=1 to 5 by 1% + {\setcounter{qr@j}{\the\qr@b}% + \qr@for \j=1 to 5 by 1% + {\qr@copymatrixentry{alignmentpattern}{\the\i}{\the\j}% + {#1}{\theqr@i}{\theqr@j}% + \stepcounter{qr@j}% + }% + \stepcounter{qr@i}% + }% +}% + +\newif\ifqr@incorner% +\def\qr@placealignmentpatterns#1{% + %There are k^2-3 alignment patterns, + %arranged in a (k x k) grid within the matrix. + %They begin in row 7, column 7, + %except that the ones in the NW, NE, and SW corners + %are omitted because of the finder patterns. + %Recall that + % * \qr@k stores k, + % * \qr@alignment@firstskip stores how far between the 1st and 2nd row/col, & + % * \qr@alignment@generalskip stores how far between each subsequent row/col. + \xa\ifnum\qr@k>0\relax + %There will be at least one alignment pattern. + %N.B. k cannot equal 1. + \xa\ifnum\qr@k=2\relax + % 2*2-3 = exactly 1 alignment pattern. + \qr@a=7\relax + \advance\qr@a by \qr@alignment@firstskip\relax + \xdef\qr@target@ii{\the\qr@a}% + \qr@placealignmentpattern@int{#1}{\qr@target@ii}{\qr@target@ii}% + \else + % k is at least 3, so the following loops should be safe. + \xdef\qr@target@ii{7}% + \qr@for \ii = 1 to \qr@k by 1% + {\ifcase\ii\relax% + \relax% \ii should never equal 0. + \or + \xdef\qr@target@ii{7}% If \ii = 1, we start in row 7. + \or + %If \ii = 2, we add the firstskip. + \qr@a=\qr@target@ii\relax% + \advance\qr@a by \qr@alignment@firstskip\relax% + \xdef\qr@target@ii{\the\qr@a}% + \else + %If \ii>2, we add the generalskip. + \qr@a=\qr@target@ii\relax% + \advance\qr@a by \qr@alignment@generalskip\relax% + \xdef\qr@target@ii{\the\qr@a}% + \fi + \qr@for \jj = 1 to \qr@k by 1% + {\ifcase\jj\relax% + \relax% \jj should never equal 0. + \or + \xdef\qr@target@jj{7}% If \jj=1, we start in row 7. + \or + %If \jj=2, we add the firstskip. + \qr@a=\qr@target@jj\relax% + \advance\qr@a by \qr@alignment@firstskip% + \xdef\qr@target@jj{\the\qr@a}% + \else + %If \jj>2, we add the generalskip. + \qr@a=\qr@target@jj\relax% + \advance\qr@a by \qr@alignment@generalskip% + \xdef\qr@target@jj{\the\qr@a}% + \fi + \qr@incornerfalse% + \ifnum\ii=1\relax + \ifnum\jj=1\relax + \qr@incornertrue + \else + \ifnum\qr@k=\jj\relax + \qr@incornertrue + \fi + \fi + \else + \xa\ifnum\qr@k=\ii\relax + \ifnum\jj=1\relax + \qr@incornertrue + \fi + \fi + \fi + \ifqr@incorner + \relax + \else + \qr@placealignmentpattern@int{#1}{\qr@target@ii}{\qr@target@jj}% + \fi + }% ends \qr@for \jj + }% ends \qr@for \ii + \fi + \fi +}% + +\def\qr@placedummyformatpatterns#1{% + \qr@for \j = 1 to 9 by 1% + {\ifnum\j=7\relax% + \else% + \qr@storetomatrix{#1}{9}{\the\j}{\qr@format@square}% + \qr@storetomatrix{#1}{\the\j}{9}{\qr@format@square}% + \fi% + }% + \setcounter{qr@j}{\qr@size}% + \qr@for \j = 1 to 8 by 1% + {\qr@storetomatrix{#1}{9}{\theqr@j}{\qr@format@square}% + \qr@storetomatrix{#1}{\theqr@j}{9}{\qr@format@square}% + \addtocounter{qr@j}{-1}% + }% + %Now go back and change the \qr@format@square in (n-8,9) to \qr@black@fixed. + \addtocounter{qr@j}{1}% + \qr@storetomatrix{#1}{\theqr@j}{9}{\qr@black@fixed}% +}% + +\def\qr@placedummyversionpatterns#1{% + \xa\ifnum\qr@version>6\relax + %Must include version information. + \global\c@qr@i=\qr@size% + \global\advance\c@qr@i by -10\relax% + \qr@for \i = 1 to 3 by 1% + {\qr@for \j = 1 to 6 by 1% + {\qr@storetomatrix{#1}{\theqr@i}{\the\j}{\qr@format@square}% + \qr@storetomatrix{#1}{\the\j}{\theqr@i}{\qr@format@square}% + }% + \stepcounter{qr@i}% + }% + \fi +}% + +\def\qr@writebit(#1#2)#3{% + % #3 = matrix name + % (qr@i,qr@j) = position to write in (LaTeX counters) + % #1 = bit to be written + % #2 = remaining bits plus '\relax' as an end-of-file marker + \edef\qr@datatowrite{#2}% + \ifnum#1=1 + \qr@storetomatrix{#3}{\theqr@i}{\theqr@j}{\qr@black}% + \else + \qr@storetomatrix{#3}{\theqr@i}{\theqr@j}{\qr@white}% + \fi +}% + +\newif\ifqr@rightcol +\newif\ifqr@goingup + +\def\qr@writedata@hex#1#2{% + % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc. + % #2 = a string consisting of bytes to write into the matrix, in two-char hex format. + \setcounter{qr@i}{\qr@numberofrowsinmatrix{#1}}% + \setcounter{qr@j}{\qr@numberofcolsinmatrix{#1}}% + \qr@rightcoltrue% + \qr@goinguptrue% + \edef\qr@argument{{#1}(#2\relax\relax\relax)}% + \xa\qr@writedata@hex@recursive\qr@argument% +}% + +\def\qr@writedata@hex@recursive#1(#2#3#4){% + % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc. + % (qr@i,qr@j) = position to write in LaTeX counters + % #2#3#4 contains the hex codes of the bytes to be written, plus \relax\relax\relax + % as an end-of-file marker + \edef\qr@testii{#2}% + \ifx\qr@testii\qr@relax% + % #2 is \relax, so there is nothing more to write. + \relax + \let\qr@next=\relax + \else + % #2 is not \relax, so there is another byte to write. + \qr@hextobinary[8]{\bytetowrite}{#2#3}% + \xdef\qr@datatowrite{\bytetowrite\relax}% %Add terminating "\relax" + \qr@writedata@recursive{#1}% %This function actually writes the 8 bits. + \edef\qr@argument{{#1}(#4)}% + \xa\def\xa\qr@next\xa{\xa\qr@writedata@hex@recursive\qr@argument}% %Call self to write the next bit. + \fi + \qr@next +}% + +\def\qr@writedata#1#2{% + % #1 = name of a matrix that has been prepared with finder patterns, timing patterns, etc. + % #2 = a string consisting of 0's and 1's to write into the matrix. + \setcounter{qr@i}{\qr@numberofrowsinmatrix{#1}}% + \setcounter{qr@j}{\qr@numberofcolsinmatrix{#1}}% + \qr@rightcoltrue + \qr@goinguptrue + \edef\qr@datatowrite{#2\relax}% + \qr@writedata@recursive{#1}% +}% + +\def\qr@@blank{\qr@blank}% + +\def\qr@writedata@recursive#1{% + % #1 = matrix name + % (qr@i,qr@j) = position to write in (LaTeX counters) + % \qr@datatowrite contains the bits to be written, plus '\relax' as an end-of-file marker + \xa\let\xa\squarevalue\csname #1@\theqr@i @\theqr@j\endcsname% + \ifx\squarevalue\qr@@blank + %Square is blank, so write data in it. + \xa\qr@writebit\xa(\qr@datatowrite){#1}% + %The \qr@writebit macro not only writes the first bit of \qr@datatowrite into the matrix, + %but also removes the bit from the 'bitstream' of \qr@datatowrite. + \fi + %Now adjust our position in the matrix. + \ifqr@rightcol + %From the right-hand half of the two-bit column, we always move left. Easy peasy. + \addtocounter{qr@j}{-1}% + \qr@rightcolfalse + \else + %If we're in the left-hand column, things are harder. + \ifqr@goingup + %First, suppose we're going upwards. + \ifnum\c@qr@i>1\relax% + %If we're not in the first row, things are easy. + %We move one to the right and one up. + \addtocounter{qr@j}{1}% + \addtocounter{qr@i}{-1}% + \qr@rightcoltrue + \else + %If we are in the first row, then we move to the left, + %and we are now in the right-hand column on a downward pass. + \addtocounter{qr@j}{-1}% + \qr@goingupfalse + \qr@rightcoltrue + \fi + \else + %Now, suppose we're going downwards. + \xa\ifnum\qr@size>\c@qr@i\relax% + %If we're not yet in the bottom row, things are easy. + %We move one to the right and one down. + \addtocounter{qr@j}{1}% + \addtocounter{qr@i}{1}% + \qr@rightcoltrue + \else + %If we are in the bottom row, then we move to the left, + %and we are now in the right-hand column on an upward pass. + \addtocounter{qr@j}{-1}% + \qr@rightcoltrue + \qr@goinguptrue + \fi + \fi + %One problem: what if we just moved into the 7th column? + %Das ist verboten. + %If we just moved (left) into the 7th column, we should move on into the 6th column. + \ifnum\c@qr@j=7\relax% + \setcounter{qr@j}{6}% + \fi + \fi + %Now check whether there are any more bits to write. + \ifx\qr@datatowrite\qr@relax + % \qr@datatowrite is just `\relax', so we're done. + \let\qr@next=\relax + \relax + \else + % Write some more! + \def\qr@next{\qr@writedata@recursive{#1}}% + \fi + \qr@next +}% + +\def\qr@writeremainderbits#1{% + % #1 = name of a matrix that has been prepared and partly filled. + % (qr@i,qr@j) = position to write in LaTeX counters + \xa\ifnum\qr@numremainderbits>0\relax + \def\qr@datatowrite{}% + \qr@for \i = 1 to \qr@numremainderbits by 1% + {\g@addto@macro{\qr@datatowrite}{0}}% + \g@addto@macro{\qr@datatowrite}{\relax}% terminator + \qr@writedata@recursive{#1}% + \fi +}% + +\newif\ifqr@cellinmask + +\def\qr@setmaskingfunction#1{% + % #1 = 1 decimal digit for the mask. (I see no reason to use the 3-bit binary code.) + % The current position is (\themaski,\themaskj), with indexing starting at 0. + \edef\qr@maskselection{#1}% + \xa\ifcase\qr@maskselection\relax + %Case 0: checkerboard + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski+\themaskj,2)% + \qr@a=\c@maski% + \advance\qr@a by \c@maskj% + \qr@b=\qr@a% + \divide\qr@b by 2% + \multiply\qr@b by 2% + \advance\qr@a by -\qr@b% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 1: horizontal stripes + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski,2)% + \ifodd\c@maski\relax% + \def\qr@maskfunctionresult{1}% + \else% + \def\qr@maskfunctionresult{0}% + \fi% + }% + \or + %Case 2: vertical stripes + \def\qr@parsemaskingfunction{% + % Compute mod(\themaskj,3)% + \qr@a=\c@maskj% + \divide\qr@a by 3% + \multiply\qr@a by 3% + \advance\qr@a by -\c@maskj% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 3: diagonal stripes + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski+\themaskj,3)% + \qr@a=\c@maski% + \advance\qr@a by \c@maskj% + \qr@b=\qr@a% + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@b by -\qr@a% + \edef\qr@maskfunctionresult{\the\qr@b}% + }% + \or + %Case 4: wide checkerboard + \def\qr@parsemaskingfunction{% + % Compute mod(floor(\themaski/2) + floor(\themaskj/3),2) % + \qr@a=\c@maski% + \divide\qr@a by 2% + \qr@b=\c@maskj% + \divide\qr@b by 3% + \advance\qr@a by \qr@b% + \qr@b=\qr@a% + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@a by -\qr@b% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 5: quilt + \def\qr@parsemaskingfunction{% + % Compute mod(\themaski*\themaskj,2) + mod(\themaski*\themaskj,3) % + \qr@a=\c@maski% + \multiply\qr@a by \c@maskj% + \qr@b=\qr@a% + \qr@c=\qr@a% + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@a by -\qr@c% (result will be -mod(i*j,2), which is negative.) + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@b by -\qr@c% (result will be -mod(i*j,3), which is negative.) + \advance\qr@a by \qr@b% (result is negative of what's in the spec.) + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \or + %Case 6: arrows + \def\qr@parsemaskingfunction{% + % Compute mod( mod(\themaski*\themaskj,2) + mod(\themaski*\themaskj,3) , 2 ) % + \qr@a=\c@maski% + \multiply\qr@a by \c@maskj% + \qr@b=\qr@a% + \qr@c=\qr@a% + \multiply\qr@c by 2% % \qr@c equals 2*i*j. + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@c by -\qr@a% Now \qr@c equals i*j + mod(i*j,2). + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@c by -\qr@b% (Now \qr@c equals mod(i*j,2) + mod(i*j,3). + \qr@a=\qr@c% + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@c by-\qr@a% + \edef\qr@maskfunctionresult{\the\qr@c}% + }% + \or + %Case 7: shotgun + \def\qr@parsemaskingfunction{% + % Compute mod( mod(\themaski+\themaskj,2) + mod(\themaski*\themaskj,3) , 2 ) % + \qr@a=\c@maski% + \advance\qr@a by \c@maskj% %So \qr@a = i+j + \qr@b=\c@maski% + \multiply\qr@b by \c@maskj% %So \qr@b = i*j + \qr@c=\qr@a% + \advance\qr@c by \qr@b% So \qr@c = i+j+i*j + \divide\qr@a by 2% + \multiply\qr@a by 2% + \advance\qr@c by -\qr@a% So \qr@c = mod(i+j,2) + i*j + \divide\qr@b by 3% + \multiply\qr@b by 3% + \advance\qr@c by -\qr@b% So \qr@c = mod(i+j,2) + mod(i*j,3) + \qr@a=\qr@c% + \divide\qr@c by 2% + \multiply\qr@c by 2% + \advance\qr@a by -\qr@c% + \edef\qr@maskfunctionresult{\the\qr@a}% + }% + \fi +}% + +\def\qr@checkifcellisinmask{% + % The current position is (\i,\j), in TeX counts, + % but the LaTeX counters (maski,maskj) should contain + % the current position with indexing starting at 0. + % That is, maski = \i-1 and maskj = \j-1. + % + % \qr@parsemaskingfunction must have been set by a call to \qr@setmaskingfunction + \qr@parsemaskingfunction + \xa\ifnum\qr@maskfunctionresult=0\relax + \qr@cellinmasktrue + \else + \qr@cellinmaskfalse + \fi +}% + +\newcounter{maski}% +\newcounter{maskj}% + +\def\qr@applymask#1#2#3{% + % #1 = name of a matrix that should be filled out completely + % except for the format and/or version information. + % #2 = name of a new matrix to contain the masked version + % #3 = 1 decimal digit naming the mask + \qr@createduplicatematrix{#2}{#1}% + \qr@setmaskingfunction{#3}% + \setcounter{maski}{-1}% + \qr@for \i = 1 to \qr@size by 1% + {\stepcounter{maski}% + \setcounter{maskj}{-1}% + \qr@for \j = 1 to \qr@size by 1% + {\stepcounter{maskj}% + \qr@checkifcellisinmask + \ifqr@cellinmask + \qr@checkifcurrentcellcontainsdata{#2}% + \ifqr@currentcellcontainsdata + \qr@flipcurrentcell{#2}% + \fi + \fi + }% + }% +}% + +\newif\ifqr@currentcellcontainsdata +\qr@currentcellcontainsdatafalse + +\def\qr@@white{\qr@white}% +\def\qr@@black{\qr@black}% + +\def\qr@checkifcurrentcellcontainsdata#1{% + % #1 = name of matrix + \qr@currentcellcontainsdatafalse + \xa\ifx\csname #1@\the\i @\the\j\endcsname\qr@@white + \qr@currentcellcontainsdatatrue + \fi + \xa\ifx\csname #1@\the\i @\the\j\endcsname\qr@@black + \qr@currentcellcontainsdatatrue + \fi +}% + +\def\qr@flipped@black{\qr@black}% +\def\qr@flipped@white{\qr@white}% + +\def\qr@flipcurrentcell#1{% + % #1 = name of matrix + % (\i, \j) = current position, in TeX counts. + % This assumes the cell contains data, either black or white! + \xa\ifx\csname #1@\the\i @\the\j\endcsname\qr@@white + \qr@storetomatrix{#1}{\the\i}{\the\j}{\qr@flipped@black}% + \else + \qr@storetomatrix{#1}{\the\i}{\the\j}{\qr@flipped@white}% + \fi +}% + +\def\qr@chooseandapplybestmask#1{% + % #1 = name of a matrix that should be filled out completely + % except for the format and/or version information. + % This function applies all eight masks in succession, + % calculates their penalties, and remembers the best. + % The number indicating which mask was used is saved in \qr@mask@selected. + \qr@createduplicatematrix{originalmatrix}{#1}% + \message{^^J}% + \gdef\qr@currentbestmask{0}% + \qr@for \i = 1 to 7 by 1% + {\message{^^J}% + \xa\xa\xa\ifnum\xa\qr@penalty\xa<\qr@currentbestpenalty\relax + %We found a better mask. + \xdef\qr@currentbestmask{\the\i}% + \qr@createduplicatematrix{#1}{currentmasked}% + \xdef\qr@currentbestpenalty{\qr@penalty}% + \fi + }% + \xdef\qr@mask@selected{\qr@currentbestmask}% + \message{^^J}% +}% + +\def\qr@Ni{3}% +\def\qr@Nii{3}% +\def\qr@Niii{40}% +\def\qr@Niv{10}% +\def\qr@fiveones{11111}% +\def\qr@fivezeros{11111}% +\def\qr@twoones{11}% +\def\qr@twozeros{00}% +\def\qr@finderA{00001011101}% +\def\qr@finderB{10111010000}% +\def\qr@finderB@three{1011101000}% +\def\qr@finderB@two{101110100}% +\def\qr@finderB@one{10111010}% +\def\qr@finderB@zero{1011101}% +\newif\ifqr@stringoffive +\def\qr@addpenaltyiii{% + \addtocounter{penaltyiii}{\qr@Niii}% +}% +\newcounter{totalones}% +\newcounter{penaltyi}% +\newcounter{penaltyii}% +\newcounter{penaltyiii}% +\newcounter{penaltyiv}% +\def\qr@evaluatemaskpenalty#1{% + % #1 = name of a matrix that we will test for the penalty + % according to the specs. + \setcounter{penaltyi}{0}% + \setcounter{penaltyii}{0}% + \setcounter{penaltyiii}{0}% + \setcounter{penaltyiv}{0}% + \bgroup%localize the meanings we give to the symbols + \def\qr@black{1}\def\qr@white{0}% + \def\qr@black@fixed{1}\def\qr@white@fixed{0}% + \def\qr@format@square{0}% This is not stated in the specs, but seems + % to be the standard implementation. + \def\qr@blank{0}% These would be any bits at the end. + % + \setcounter{totalones}{0}% + \qr@for \i=1 to \qr@size by 1% + {\def\qr@lastfive{z}% %The z is a dummy, that will be removed before any testing. + \qr@stringoffivefalse + \def\qr@lasttwo@thisrow{z}% %The z is a dummy. + \def\qr@lasttwo@nextrow{z}% %The z is a dummy. + \def\qr@lastnine{z0000}% %The 0000 stands for the white space to the left. The z is a dummy. + \def\qr@ignore@finderB@at{0}% + \qr@for \j=1 to \qr@size by 1% + {\edef\qr@newbit{\qr@matrixentry{#1}{\the\i}{\the\j}}% + % + % LASTFIVE CODE FOR PENALTY 1 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastfive\xa{\qr@newbit}% + \ifnum\j<5\relax% + %Not yet on the 5th entry. + %Don't do any testing. + \else + % 5th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastfive% + \ifx\qr@lastfive\qr@fiveones% + \ifqr@stringoffive% + %This is a continuation of a previous block of five or more 1's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 1's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + \ifx\qr@lastfive\qr@fivezeros% + \ifqr@stringoffive + %This is a continuation of a previous block of five or more 0's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 0's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + %This is not a string of five 1's or five 0's. + \global\qr@stringoffivefalse + \fi + \fi + \fi + % + % 2x2 BLOCKS FOR PENALTY 2 + % Every 2x2 block of all 1's counts for \qr@Nii penalty points. + % We do not need to run this test in the last row. + \xa\ifnum\xa\i\xa<\qr@size\relax + \xa\g@addto@macro\xa\qr@lasttwo@thisrow\xa{\qr@newbit}% + %Compute \qr@iplusone + \qr@a=\i\relax% + \advance\qr@a by 1% + \edef\qr@iplusone{\the\qr@a}% + % + \edef\qr@nextrowbit{\qr@matrixentry{#1}{\qr@iplusone}{\the\j}}% + \xa\g@addto@macro\xa\qr@lasttwo@nextrow\xa{\qr@nextrowbit}% + \ifnum\j<2\relax% + %Still in the first column; no check. + \else + %Second column or later. Remove the old bits, and then test. + \qr@removefirsttoken\qr@lasttwo@thisrow + \qr@removefirsttoken\qr@lasttwo@nextrow + \ifx\qr@lasttwo@thisrow\qr@twoones + \ifx\qr@lasttwo@nextrow\qr@twoones + \addtocounter{penaltyii}{\qr@Nii}% + \fi + \else + \ifx\qr@lasttwo@thisrow\qr@twozeros + \ifx\qr@lasttwo@nextrow\qr@twozeros + \addtocounter{penaltyii}{\qr@Nii}% + \fi + \fi + \fi + \fi + \fi + % + % LASTNINE CODE FOR PENALTY 3 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastnine\xa{\qr@newbit}% + \ifnum\j<7\relax% + %Not yet on the 7th entry. + %Don't do any testing. + \else + % 7th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastnine + \xa\ifnum\qr@size=\j\relax% + % Last column. Any of the following should count: + % 1011101 (\qr@finderB@zero) + % 10111010 (\qr@finderB@one) + % 101110100 (\qr@finderB@two) + % 1011101000 (\qr@finderB@three) + % 10111010000 (\qr@finderB) + \ifx\qr@lastnine\qr@finderB + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@three + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@two + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@one + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@zero + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + \else + \ifx\qr@lastnine\qr@finderA% %Matches 0000 1011101 + \qr@addpenaltyiii + %Also, we record our discovery, so that we can't count this pattern again + %if it shows up four columns later as 1011101 0000. + % + %Set \qr@ignore@finderB@at to \j+4. + \qr@a=\j\relax% + \advance\qr@a by 4% + \xdef\qr@ignore@finderB@at{\the\qr@a}% + \else + \ifx\qr@lastfive\qr@finderB% %Matches 1011101 0000. + \xa\ifnum\qr@ignore@finderB@at=\j\relax + %This pattern was *not* counted already earlier. + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + % + %COUNT 1's FOR PENALTY 4 + \xa\ifnum\qr@newbit=1\relax% + \stepcounter{totalones}% + \fi + }% end of j-loop + }% end of i-loop + % + %NOW WE ALSO NEED TO RUN DOWN THE COLUMNS TO FINISH CALCULATING PENALTIES 1 AND 3. + \qr@for \j=1 to \qr@size by 1% + {\def\qr@lastfive{z}% %The z is a dummy, that will be removed before any testing. + \qr@stringoffivefalse + \def\qr@lastnine{z0000}% %The 0000 stands for the white space to the left. The z is a dummy. + \def\qr@ignore@finderB@at{0}% + \qr@for \i=1 to \qr@size by 1% + {\edef\qr@newbit{\qr@matrixentry{#1}{\the\i}{\the\j}}% + % + % LASTFIVE CODE FOR PENALTY 1 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastfive\xa{\qr@newbit}% + \ifnum\i<5\relax% + %Not yet on the 5th entry. + %Don't do any testing. + \else + % 5th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastfive% + \ifx\qr@lastfive\qr@fiveones% + \ifqr@stringoffive% + %This is a continuation of a previous block of five or more 1's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 1's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + \ifx\qr@lastfive\qr@fivezeros% + \ifqr@stringoffive + %This is a continuation of a previous block of five or more 0's. + \stepcounter{penaltyi}% + \else + %This is a new string of five 0's. + \addtocounter{penaltyi}{\qr@Ni}% + \global\qr@stringoffivetrue + \fi + \else + %This is not a string of five 1's or five 0's. + \global\qr@stringoffivefalse + \fi + \fi + \fi + % + % HAPPILY, WE DON'T NEED TO CALCULATE PENALTY 2 AGAIN. + % + % LASTNINE CODE FOR PENALTY 3 + % First, add the new bit to the end. + \xa\g@addto@macro\xa\qr@lastnine\xa{\qr@newbit}% + \ifnum\i<7\relax% + %Not yet on the 7th entry. + %Don't do any testing. + \else + % 7th entry or later. + % Remove the old one, and then test. + \qr@removefirsttoken\qr@lastnine + \xa\ifnum\qr@size=\i\relax% + % Last column. Any of the following should count: + % 1011101 (\qr@finderB@zero) + % 10111010 (\qr@finderB@one) + % 101110100 (\qr@finderB@two) + % 1011101000 (\qr@finderB@three) + % 10111010000 (\qr@finderB) + \ifx\qr@lastnine\qr@finderB + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@three + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@two + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@one + \qr@addpenaltyiii + \else + \qr@removefirsttoken\qr@lastnine + \ifx\qr@lastnine\qr@finderB@zero + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + \else + \ifx\qr@lastnine\qr@finderA% %Matches 0000 1011101 + \qr@addpenaltyiii + %Also, we record our discovery, so that we can't count this pattern again + %if it shows up four columns later as 1011101 0000. + % + %Set \qr@ignore@finderB@at to \i+4. + \qr@a=\i\relax% + \advance\qr@a by 4% + \xdef\qr@ignore@finderB@at{\the\qr@a}% + \else + \ifx\qr@lastfive\qr@finderB% %Matches 1011101 0000. + \xa\ifnum\qr@ignore@finderB@at=\i\relax + %This pattern was *not* counted already earlier. + \qr@addpenaltyiii + \fi + \fi + \fi + \fi + \fi + % + }% end of i-loop + }% end of j-loop + \egroup% + % + %CALCULATE PENALTY 4 + %According to the spec, penalty #4 is computed as + % floor( |(i/n^2)-0.5|/0.05 ) + % where i is the total number of 1's in the matrix. + % This is equal to abs(20*i-10n^2) div n^2. + % + \qr@a=\c@totalones\relax + \multiply\qr@a by 20\relax + \qr@b=\qr@size\relax + \multiply\qr@b by \qr@size\relax + \qr@c=10\relax + \multiply\qr@c by \qr@b\relax + \advance\qr@a by -\qr@c\relax + \ifnum\qr@a<0\relax + \multiply\qr@a by -1\relax + \fi + \divide\qr@a by \qr@b\relax + \setcounter{penaltyiv}{\the\qr@a}% + % + %CALCULATE TOTAL PENALTY + \qr@a=\thepenaltyi\relax% + \advance\qr@a by \thepenaltyii\relax% + \advance\qr@a by \thepenaltyiii\relax% + \advance\qr@a by \thepenaltyiv\relax% + \edef\qr@penalty{\the\qr@a}% +}% + +\def\qr@removefirsttoken#1{% + %Removes the first token from the macro named in #1. + \edef\qr@argument{(#1)}% + \xa\qr@removefirsttoken@int\qr@argument% + \xdef#1{\qr@removefirsttoken@result}% +}% +\def\qr@removefirsttoken@int(#1#2){% + \def\qr@removefirsttoken@result{#2}% +}% + +\def\qr@writeformatstring#1#2{% + % #1 = matrix name + % #2 = binary string representing the encoded and masked format information + \setcounter{qr@i}{9}% + \setcounter{qr@j}{1}% + \edef\qr@argument{{#1}(#2\relax)}% + \xa\qr@writeformatA@recursive\qr@argument + % + \setcounter{qr@i}{\qr@numberofrowsinmatrix{#1}}% + \setcounter{qr@j}{9}% + \xa\qr@writeformatB@recursive\qr@argument +}% + +\def\qr@writeformatA@recursive#1(#2#3){% + % #1 = matrix name + % #2 = first bit of string + % #3 = rest of bitstream + % (qr@i,qr@j) = current (valid) position to write (in LaTeX counters) + \ifnum#2=1\relax + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@black@format}% + \else + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@white@format}% + \fi + % Now the tricky part--moving \i and \j to their next positions. + \ifnum\c@qr@j<9\relax + %If we're not yet in column 9, move right. + \stepcounter{qr@j}% + \ifnum\c@qr@j=7\relax + %But we skip column 7! + \stepcounter{qr@j}% + \fi + \else + %If we're in column 9, we move up. + \addtocounter{qr@i}{-1}% + \ifnum\c@qr@i=7\relax + %But we skip row 7! + \addtocounter{qr@i}{-1}% + \fi + \fi + %N.B. that at the end of time, this will leave us at invalid position (0,9). + %That makes for an easy test to know when we are done. + \ifnum\c@qr@i<1 + \let\qr@next=\relax + \else + \def\qr@next{\qr@writeformatA@recursive{#1}(#3)}% + \fi + \qr@next +}% + +\def\qr@writeformatB@recursive#1(#2#3){% + % #1 = matrix name + % #2 = first bit of string + % #3 = rest of bitstream + % (qr@i,qr@j) = current (valid) position to write (in LaTeX counters) + \ifnum#2=1\relax + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@black@format}% + \else + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@white@format}% + \fi + % Now the tricky part--moving counters i and j to their next positions. + \qr@a=\qr@size% + \advance\qr@a by -6\relax% + \ifnum\qr@a<\c@qr@i\relax + %If we're not yet in row n-6, move up. + \addtocounter{qr@i}{-1}% + \else + \ifnum\qr@a=\c@qr@i\relax + %If we're actually in row n-6, we jump to position (9,n-7). + \setcounter{qr@i}{9}% + %Set counter j equal to \qr@size-7. + \global\c@qr@j=\qr@size\relax% + \global\advance\c@qr@j by -7\relax% + \else + %Otherwise, we must be in row 9. + %In this case, we move right. + \stepcounter{qr@j}% + \fi + \fi + %N.B. that at the end of time, this will leave us at invalid position (9,n+1). + %That makes for an easy test to know when we are done. + \xa\ifnum\qr@size<\c@qr@j\relax + \let\qr@next=\relax + \else + \def\qr@next{\qr@writeformatB@recursive{#1}(#3)}% + \fi + \qr@next +}% + +\def\qr@writeversionstring#1#2{% + % #1 = matrix name + % #2 = binary string representing the encoded version information + % + % Plot the encoded version string into the matrix. + % This is only done for versions 7 and higher. + \xa\ifnum\qr@version>6\relax + %Move to position (n-8,6). + \setcounter{qr@i}{\qr@size}\relax% + \addtocounter{qr@i}{-8}\relax% + \setcounter{qr@j}{6}% + \edef\qr@argument{{#1}(#2\relax)}% + \xa\qr@writeversion@recursive\qr@argument + \fi +}% + +\def\qr@writeversion@recursive#1(#2#3){% + % #1 = matrix name + % #2 = first bit of string + % #3 = rest of bitstream + % (qr@i,qr@j) = current (valid) position to write (in LaTeX counters) + % + % The version information is stored symmetrically in the matrix + % In two transposed regions, so we can write both at the same time. + % In the comments, we describe what happens in the lower-left region, + % not the upper-right. + % + %Set \qr@topline equal to n-10. + \qr@a=\qr@size\relax% + \advance\qr@a by -10\relax% + \edef\qr@topline{\the\qr@a}% + % + \ifnum#2=1\relax + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@black@format}% + \qr@storetomatrix{#1}{\theqr@j}{\theqr@i}{\qr@black@format}% + \else + \qr@storetomatrix{#1}{\theqr@i}{\theqr@j}{\qr@white@format}% + \qr@storetomatrix{#1}{\theqr@j}{\theqr@i}{\qr@white@format}% + \fi + % Now the tricky part--moving counters i and j to their next positions. + \addtocounter{qr@i}{-1}% + \xa\ifnum\qr@topline>\c@qr@i\relax + %We've overshot the top of the region. + %We need to move left one column and down three. + \addtocounter{qr@j}{-1}% + \addtocounter{qr@i}{3}% + \fi + %N.B. that at the end of time, this will leave us at invalid position (n-8,0). + %That makes for an easy test to know when we are done. + \ifnum\c@qr@j<1\relax + \let\qr@next=\relax + \else + \def\qr@next{\qr@writeversion@recursive{#1}(#3)}% + \fi + \qr@next +}% +\newcounter{qr@hexchars}% + +\def\qr@string@binarytohex#1{% + \qr@binarytohex{\qr@hex@result}{#1}% +}% + +\def\qr@encode@binary#1{% + % #1 = string of ascii characters, to be converted into bitstream + % + % We do this one entirely in hex, rather than binary, because we can. + \edef\qr@plaintext{#1}% + % + %First, the mode indicator. + \def\qr@codetext{4}% %This means `binary' + % + %Next, the character count. + \qr@getstringlength{\qr@plaintext}% + %Set \qr@charactercountlengthinhex to \qr@charactercountbits@byte/4% + \qr@a=\qr@charactercountbits@byte\relax% + \divide \qr@a by 4\relax% + \edef\qr@charactercountlengthinhex{\the\qr@a}% + \qr@decimaltohex[\qr@charactercountlengthinhex]{\qr@charactercount}{\qr@stringlength}% + \xa\g@addto@macro\xa\qr@codetext\xa{\qr@charactercount}% + % + %Now comes the actual data. + \edef\qr@argument{(,\qr@plaintext\relax\relax\relax)}% + \xa\qr@encode@ascii@recursive\qr@argument% + % + %Now the terminator. + \g@addto@macro\qr@codetext{0}% %This is '0000' in binary. + % + %There is no need to pad bits to make a multiple of 8, + %because the data length is already 4 + 8 + 8n + 4. + % + %Now add padding codewords if needed. + \setcounter{qr@hexchars}{0}% + \qr@getstringlength{\qr@codetext}% + \setcounter{qr@hexchars}{\qr@stringlength}% + %Set \qr@numpaddingcodewords equal to \qr@totaldatacodewords - qr@hexchars/2. + \qr@a=-\c@qr@hexchars\relax + \divide\qr@a by 2\relax + \advance\qr@a by \qr@totaldatacodewords\relax + \edef\qr@numpaddingcodewords{\the\qr@a}% + % + \xa\ifnum\qr@numpaddingcodewords<0% + \edef\ds{ERROR: Too much data! Over by \qr@numpaddingcodewords bytes.}\show\ds% + \fi% + \xa\ifnum\qr@numpaddingcodewords>0% + \qr@for \i = 2 to \qr@numpaddingcodewords by 2% + {\g@addto@macro{\qr@codetext}{ec11}}% + \xa\ifodd\qr@numpaddingcodewords\relax% + \g@addto@macro{\qr@codetext}{ec}% + \fi% + \fi% +}% + +\def\qr@encode@ascii@recursive(#1,#2#3){% + % #1 = hex codes translated so far + % #2 = next plaintext character to translate + % #3 = remainder of plaintext + \edef\qr@testii{#2}% + \ifx\qr@testii\qr@relax% + % All done! + \g@addto@macro\qr@codetext{#1}% + \else% + % Another character to translate. + \edef\qr@asciicode{\number`#2}% + \qr@decimaltohex[2]{\qr@newhexcodes}{\qr@asciicode}% + \edef\qr@argument{(#1\qr@newhexcodes,#3)}% + %\show\qr@argument + \xa\qr@encode@ascii@recursive\qr@argument% + \fi% +}% + +\def\qr@splitcodetextintoblocks{% + \setcounter{qr@i}{0}% + \qr@for \j = 1 to \qr@numshortblocks by 1% + {\stepcounter{qr@i}% + \qr@splitoffblock{\qr@codetext}{\theqr@i}{\qr@shortblock@size}% + }% + \xa\ifnum\qr@numlongblocks>0\relax% + \qr@for \j = 1 to \qr@numlongblocks by 1% + {\stepcounter{qr@i}% + \qr@splitoffblock{\qr@codetext}{\theqr@i}{\qr@longblock@size}% + }% + \fi% +}% + +\def\qr@splitoffblock#1#2#3{% + % #1 = current codetext in hexadecimal + % #2 = number to use in csname "\datablock@#2". + % #3 = number of bytes to split off + \message{}% + \xa\gdef\csname datablock@#2\endcsname{}% %This line is important! + \qr@for \i = 1 to #3 by 1% + {\edef\qr@argument{{#2}(#1)}% + \xa\qr@splitoffblock@int\qr@argument% + }% +}% + +\def\qr@splitoffblock@int#1(#2#3#4){% + % #1 = number to use in csname "\datablock@#1". + % #2#3 = next byte to split off + % #4 = remaining text + % + % We add the next byte to "\datablock@#1", + % and we remove it from the codetext. + \xa\xdef\csname datablock@#1\endcsname{\csname datablock@#1\endcsname#2#3}% + \xdef\qr@codetext{#4}% +}% + +\def\qr@createerrorblocks{% + \qr@for \ii = 1 to \qr@numblocks by 1% + {\message{}% + \FX@generate@errorbytes{\csname datablock@\the\ii\endcsname}{\qr@num@eccodewords}% + \xa\xdef\csname errorblock@\the\ii\endcsname{\FX@errorbytes}% + }% +}% + +\def\qr@interleave{% + \setcounter{qr@i}{0}% + \def\qr@interleaved@text{}% + \message{0\relax% + \message{\qr@longblock@size.>}% + \else + \message{.>}% + \fi + \message{}% +}% + +\def\qr@writefromblock#1#2{% + % #1 = either 'datablock' or 'errorblock' + % #2 = block number, in {1,...,\qr@numblocks}% + \edef\qr@argument{(\csname #1@#2\endcsname\relax\relax\relax)}% + \xa\qr@writefromblock@int\qr@argument + \xa\xdef\csname #1@#2\endcsname{\qr@writefromblock@remainder}% +}% + +\def\qr@writefromblock@int(#1#2#3){% + % #1#2 = first byte (in hex) of text, which will be written to \qr@interleaved@text + % #3 = remainder, including \relax\relax\relax terminator. + \g@addto@macro{\qr@interleaved@text}{#1#2}% + \qr@writefromblock@intint(#3)% +}% + +\def\qr@writefromblock@intint(#1\relax\relax\relax){% + \xdef\qr@writefromblock@remainder{#1}% +}% +\let\xa=\expandafter +\makeatletter + +\def\qr@preface@macro#1#2{% + % #1 = macro name + % #2 = text to add to front of macro + \def\qr@tempb{#2}% + \xa\xa\xa\gdef\xa\xa\xa#1\xa\xa\xa{\xa\qr@tempb #1}% +}% + +\newif\ifqr@leadingcoeff +\def\qr@testleadingcoeff(#1#2){% + % Tests whether the leading digit of #1#2 is 1. + \ifnum#1=1\relax + \qr@leadingcoefftrue + \else + \qr@leadingcoefffalse + \fi +}% + +\def\qr@polynomialdivide#1#2{% + \edef\qr@numerator{#1}% + \edef\qr@denominator{#2}% + \qr@divisiondonefalse% + \xa\xa\xa\qr@oneroundofdivision\xa\xa\xa{\xa\qr@numerator\xa}\xa{\qr@denominator}% +}% + +\def\@qr@empty{}% +\def\qr@oneroundofdivision#1#2{% + % #1 = f(x), of degree n + % #2 = g(x), of degree m + % Obtains a new polynomial h(x), congruent to f(x) modulo g(x), + % but of degree at most n-1. + % + % If leading coefficient of f(x) is 1, subtracts off g(x) * x^(n-m). + % If leading coefficient of f(x) is 0, strips off that leading zero. + % + \qr@testleadingcoeff(#1)% + \ifqr@leadingcoeff + \qr@xorbitstrings{#1}{#2}% + \ifqr@xorfailed + %If xor failed, that means our #1 was already the remainder! + \qr@divisiondonetrue + \edef\qr@theremainder{#1}% + \else + %xor succeeded. We need to recurse. + \xa\xa\xa\edef\xa\xa\xa\qr@numerator\xa\xa\xa{\xa\qr@stripleadingzero\xa(\qr@xorresult)}% + \fi + \else + \xa\def\xa\qr@numerator\xa{\qr@stripleadingzero(#1)}% + \ifx\qr@numerator\@qr@empty + \qr@divisiondonetrue + \def\qr@theremainder{0}% + \fi + \fi + \ifqr@divisiondone + \relax + \else + \xa\qr@oneroundofdivision\xa{\qr@numerator}{#2}% + \fi +}% + +\def\qr@stripleadingzero(0#1){#1}%Strips off a leading zero. + +\newif\ifqr@xorfailed% This flag will trigger when #2 is longer than #1. + +\def\qr@xorbitstrings#1#2{% + % #1 = bitstring + % #2 = bitstring no longer than #1 + \qr@xorfailedfalse + \edef\qr@argument{(,#1\relax\relax)(#2\relax\relax)}% + \xa\qr@xorbitstrings@recursive\qr@argument + %\qr@xorbitstrings@recursive(,#1\relax\relax)(#2\relax\relax)% +}% + +\def\qr@xorbitstrings@recursive(#1,#2#3)(#4#5){% + % #1#2#3 is the first bitstring, xor'ed up through #1. + % #4#5 is the remaining portion of the second bitstring. + \def\qr@testii{#2}% + \def\qr@testiv{#4}% + \ifx\qr@testii\qr@relax + % #1 contains the whole string. + % Now if #4 is also \relax, that means the two strings started off with equal lengths. + % If, however, #4 is not \relax, that means the second string was longer than the first, a problem. + \ifx\qr@testiv\qr@relax + %No problem. We are done. + \qr@xorbit@saveresult(#1#2#3)% + \else + %Problem! The second string was longer than the first. + \qr@xorfailedtrue + \def\qr@xorresult{}% + \fi + \else + % There is still a bit to manipulate in #2. + % Check whether #4 contains anything. + \ifx\qr@testiv\qr@relax + % No, #4 is empty. We are done. "#2#3" contains the remainder of the first string, + % which we append untouched and then strip off the two \relax-es. + \qr@xorbit@saveresult(#1#2#3)% + \else + % Yes, #4 still has something to XOR. Do the task. + \ifnum#2=#4\relax + \qr@xorbitstrings@recursive(#1% + 0,#3)(#5)% + \else + \qr@xorbitstrings@recursive(#1% + 1,#3)(#5)% + \fi + \fi + \fi +}% + +\def\qr@xorbit@saveresult(#1\relax\relax){% + %Strips off the extra '\relax'es at the end. + \def\qr@xorresult{#1}% +}% + +\newif\ifqr@divisiondone + +\def\qr@BCHcode#1{% + \edef\qr@formatinfo{#1}% + \def\qr@formatinfopadded{\qr@formatinfo 0000000000}% + \def\qr@divisor{10100110111}% + \qr@divisiondonefalse + \qr@polynomialdivide{\qr@formatinfopadded}{\qr@divisor}% + % + \qr@getstringlength{\qr@theremainder}% + %Run loop from stringlength+1 to 10. + \qr@a=\qr@stringlength\relax% + \advance\qr@a by 1\relax% + \qr@for \i = \qr@a to 10 by 1% + {\qr@preface@macro{\qr@theremainder}{0}% + \xdef\qr@theremainder{\qr@theremainder}% + }% + \edef\qr@BCHresult{\qr@formatinfo\qr@theremainder}% +}% + +\def\qr@formatmask{101010000010010}% + +\def\qr@encodeandmaskformat#1{% + \qr@BCHcode{#1}% + \qr@xorbitstrings{\qr@BCHresult}{\qr@formatmask}% + \edef\qr@format@bitstring{\qr@xorresult}% +}% + +\def\qr@Golaycode#1{% + % #1 = 6-bit version number + \edef\qr@versioninfo{#1}% + \def\qr@versioninfopadded{\qr@versioninfo 000000000000}% %Append 12 zeros. + \def\qr@divisor{1111100100101}% + \qr@divisiondonefalse + \qr@polynomialdivide{\qr@versioninfopadded}{\qr@divisor}% + % + \qr@getstringlength{\qr@theremainder}% + %Run loop from stringlength+1 to 12. + \qr@a=\qr@stringlength\relax% + \advance\qr@a by 1\relax% + \qr@for \i = \qr@a to 12 by 1% + {\qr@preface@macro{\qr@theremainder}{0}% + \xdef\qr@theremainder{\qr@theremainder}% + }% + \edef\qr@Golayresult{\qr@versioninfo\qr@theremainder}% +}% +\def\F@result{}% + +\def\qr@xorbitstring#1#2#3{% + % #1 = new macro to receive result + % #2, #3 = bitstrings to xor. The second can be shorter than the first. + \def\qr@xor@result{}% + \edef\qr@argument{(#2\relax\relax)(#3\relax\relax)}% + \xa\qr@xorbitstring@recursive\qr@argument% + \edef#1{\qr@xor@result}% +}% +\def\qr@xorbitstring@recursive(#1#2)(#3#4){% + \edef\qr@testi{#1}% + \ifx\qr@testi\qr@relax% + %Done. + \let\qr@next=\relax% + \else + \if#1#3\relax + \g@addto@macro{\qr@xor@result}{0}% + \else + \g@addto@macro{\qr@xor@result}{1}% + \fi + \edef\qr@next{\noexpand\qr@xorbitstring@recursive(#2)(#4)}% + \fi + \qr@next +} + +\def\F@addchar@raw#1#2{% + %Add two hexadecimal digits using bitwise xor + \qr@hextobinary[4]{\qr@summandA}{#1}% + \qr@hextobinary[4]{\qr@summandB}{#2}% + \qr@xorbitstring{\F@result}{\qr@summandA}{\qr@summandB}% + \qr@binarytohex[1]{\F@result}{\F@result}% +}% + +\def\qr@canceltwos#1{% + \edef\qr@argument{(#1\relax\relax)}% + \xa\qr@canceltwos@int\qr@argument% +}% + +\def\qr@canceltwos@int(#1#2){% + \xa\qr@canceltwos@recursion(,#1#2)% +}% + +\def\qr@canceltwos@recursion(#1,#2#3){% + \def\qr@testii{#2}% + \ifx\qr@testii\qr@relax + %Cancelling complete. + \qr@striptworelaxes(#1#2#3)% + %Now \F@result contains the answer. + \else + \relax + \ifnum#2=2\relax + \qr@canceltwos@recursion(#10,#3)% + \else + \qr@canceltwos@recursion(#1#2,#3)% + \fi + \fi +}% + +\def\qr@striptworelaxes(#1\relax\relax){% + \gdef\F@result{#1}% +}% + +\qr@for \i = 0 to 15 by 1% + {\qr@decimaltohex[1]{\qr@tempa}{\the\i}% + \qr@for \j = 0 to 15 by 1% + {\qr@decimaltohex[1]{\qr@tempb}{\the\j}% + \F@addchar@raw\qr@tempa\qr@tempb + \xa\xdef\csname F@addchar@\qr@tempa\qr@tempb\endcsname{\F@result}% + }% + }% + +\def\F@addchar#1#2{% + \xa\def\xa\F@result\xa{\csname F@addchar@#1#2\endcsname}% +}% + +\def\F@addstrings#1#2{% + \edef\qr@argument{(,#1\relax\relax)(#2\relax\relax)}% + \xa\F@addstrings@recursion\qr@argument% +}% + +\def\F@addstrings@recursion(#1,#2#3)(#4#5){% + %Adds two hexadecimal strings, bitwise, from left to right. + %The second string is allowed to be shorter than the first. + \def\qr@testii{#2}% + \def\qr@testiv{#4}% + \ifx\qr@testii\qr@relax + %The entire string has been processed. + \gdef\F@result{#1}% + \else + \ifx\qr@testiv\qr@relax + %The second string is over. + \qr@striptworelaxes(#1#2#3)% + %Now \F@result contains the answer. + \else + %We continue to add. + \F@addchar{#2}{#4}% + \edef\qr@argument{(#1\F@result,#3)(#5)}% + \xa\F@addstrings@recursion\qr@argument% + \fi + \fi +}% +\gdef\F@stripleadingzero(0#1){\edef\F@result{#1}}% + +\setcounter{qr@i}{0}% +\def\qr@poweroftwo{1}% +\qr@for \i = 1 to 254 by 1% + {\stepcounter{qr@i}% + \qr@a=\qr@poweroftwo\relax + \multiply\qr@a by 2\relax + \edef\qr@poweroftwo{\the\qr@a}% + %\show\qr@poweroftwo + \qr@decimaltohex[2]{\qr@poweroftwo@hex}{\qr@poweroftwo}% + \xa\ifnum\qr@poweroftwo>255\relax + %We need to bitwise add the polynomial represented by 100011101, i.e. 0x11d. + \F@addstrings{\qr@poweroftwo@hex}{11d}% %Now it should start with 0. + \xa\F@stripleadingzero\xa(\F@result)% %Now it should be two hex digits. + \edef\qr@poweroftwo@hex{\F@result}% %Save the hex version. + \qr@hextodecimal{\qr@poweroftwo}{\F@result}% + \fi + \xdef\qr@poweroftwo{\qr@poweroftwo}% + \xa\xdef\csname F@twotothe@\theqr@i\endcsname{\qr@poweroftwo@hex}% + \xa\xdef\csname F@logtwo@\qr@poweroftwo@hex\endcsname{\theqr@i}% + }% +\xa\xdef\csname F@twotothe@0\endcsname{01}% +\xa\xdef\csname F@logtwo@01\endcsname{0}% + +\def\F@twotothe#1{% + \xa\xdef\xa\F@result\xa{\csname F@twotothe@#1\endcsname}% +}% +\def\F@logtwo#1{% + \xa\xdef\xa\F@result\xa{\csname F@logtwo@#1\endcsname}% +}% + +\def\qr@zerozero{00}% + +\def\F@multiply#1#2{% + % #1 and #2 are two elements of F_256, + % given as two-character hexadecimal strings. + % Multiply them within F_256, and place the answer in \F@result + \edef\qr@argA{#1}% + \edef\qr@argB{#2}% + \ifx\qr@argA\qr@zerozero + \def\F@result{00}% + \else + \ifx\qr@argB\qr@zerozero + \def\F@result{00}% + \else + \xa\F@logtwo\xa{\qr@argA}% + \edef\qr@logA{\F@result}% + \xa\F@logtwo\xa{\qr@argB}% + \edef\qr@logB{\F@result}% + \xa\qr@a\xa=\qr@logA\relax% \qr@a = \qr@logA + \xa\advance\xa\qr@a\qr@logB\relax% \advance \qr@a by \qr@logB + \ifnum\qr@a>254\relax% + \advance\qr@a by -255\relax% + \fi% + \xa\F@twotothe\xa{\the\qr@a}% + % Now \F@result contains the product, as desired. + \fi + \fi +}% + +\def\F@multiply#1#2{% + % #1 and #2 are two elements of F_256, + % given as two-character hexadecimal strings. + % Multiply them within F_256, and place the answer in \F@result + \edef\qr@argA{#1}% + \edef\qr@argB{#2}% + \ifx\qr@argA\qr@zerozero + \def\F@result{00}% + \else + \ifx\qr@argB\qr@zerozero + \def\F@result{00}% + \else + \xa\F@logtwo\xa{\qr@argA}% + \edef\qr@logA{\F@result}% + \xa\F@logtwo\xa{\qr@argB}% + \edef\qr@logB{\F@result}% + \xa\qr@a\xa=\qr@logA\relax% \qr@a = \qr@logA + \xa\advance\xa\qr@a\qr@logB\relax% \advance \qr@a by \qr@logB + \ifnum\qr@a>254\relax% + \advance\qr@a by -255\relax% + \fi% + \xa\F@twotothe\xa{\the\qr@a}% + % Now \F@result contains the product, as desired. + \fi + \fi +}% + +\def\FX@getstringlength#1{% + %Count number of two-character coefficients + \setcounter{qr@i}{0}% + \xdef\qr@argument{(#1\relax\relax\relax)}% + \xa\FX@stringlength@recursive\qr@argument% + \xdef\stringresult{\arabic{qr@i}}% +}% + +\def\FX@stringlength@recursive(#1#2#3){% + \def\qr@testi{#1}% + \ifx\qr@testi\qr@relax + %we are done. + \else + \stepcounter{qr@i}% + %\showthe\c@qr@i + \qr@stringlength@recursive(#3)% + \fi +}% + +\newif\ifFX@leadingcoeff@zero +\def\FX@testleadingcoeff(#1#2#3){% + % Tests whether the leading coefficient of the hex-string #1#2#3 is '00'. + \edef\FX@leadingcoefficient{#1#2}% + \FX@leadingcoeff@zerofalse + \ifx\FX@leadingcoefficient\qr@zerozero + \FX@leadingcoeff@zerotrue + \fi +}% + +\newif\ifFX@divisiondone + +\newcounter{qr@divisionsremaining} %Keep track of how many divisions to go! +\def\FX@polynomialdivide#1#2{% + \edef\FX@numerator{#1}% + \edef\FX@denominator{#2}% + \qr@getstringlength\FX@numerator% + \setcounter{qr@divisionsremaining}{\qr@stringlength}% + \qr@getstringlength\FX@denominator% + \addtocounter{qr@divisionsremaining}{-\qr@stringlength}% + \addtocounter{qr@divisionsremaining}{2}% + \divide\c@qr@divisionsremaining by 2\relax% %2 hex chars per number + \FX@divisiondonefalse% + \xa\xa\xa\FX@polynomialdivide@recursive\xa\xa\xa{\xa\FX@numerator\xa}\xa{\FX@denominator}% +}% + +\def\FX@polynomialdivide@recursive#1#2{% + % #1 = f(x), of degree n + % #2 = g(x), of degree m + % Obtains a new polynomial h(x), congruent to f(x) modulo g(x), + % but of degree at most n-1. + % + % If leading coefficient of f(x) is 0, strips off that leading zero. + % If leading coefficient of f(x) is a, subtracts off a * g(x) * x^(n-m). + % N.B. we assume g is monic. + % + \FX@testleadingcoeff(#1)% + \ifFX@leadingcoeff@zero% + %Leading coefficient is zero, so remove it. + \xa\def\xa\FX@numerator\xa{\FX@stripleadingzero(#1)}% + \else% + %Leading coefficient is nonzero, and contained in \FX@leadingcoefficient + \FX@subtractphase{#1}{#2}{\FX@leadingcoefficient}% + \ifFX@subtract@failed% + %If subtraction failed, that means our #1 was already the remainder! + \FX@divisiondonetrue% + \edef\qr@theremainder{#1}% + \else% + %xor succeeded. We need to recurse. + \xa\xa\xa\edef\xa\xa\xa\FX@numerator\xa\xa\xa{\xa\FX@stripleadingzero\xa(\FX@subtraction@result)}% + \fi% + \fi% + \addtocounter{qr@divisionsremaining}{-1}% + \ifnum\c@qr@divisionsremaining=0\relax + %Division is done! + \FX@divisiondonetrue% + \edef\qr@theremainder{\FX@numerator}% + \relax% + \else% + \xa\FX@polynomialdivide@recursive\xa{\FX@numerator}{#2}% + \fi% +}% + +\def\FX@stripleadingzero(00#1){#1}%Strips off a single leading zero of F_256. + +\newif\ifFX@subtract@failed% This flag will trigger when #2 is longer than #1. + +\def\FX@subtractphase#1#2#3{% + % #1 = bitstring + % #2 = bitstring no longer than #1 + % #3 = leading coefficient + \FX@subtract@failedfalse% + \edef\qr@argument{(,#1\relax\relax\relax)(#2\relax\relax\relax)(#3)}% + \xa\FX@subtract@recursive\qr@argument% +}% + +\def\FX@subtract@recursive(#1,#2#3#4)(#5#6#7)(#8){% + % This is a recursive way to compute f(x) - a*g(x)*x^k. + % #1#2#3#4 is the first bitstring, subtracted up through #1. + % Thus #2#3 constitutes the next two-character coefficient. + % #5#6#7 is the remaining portion of the second bitstring. + % Thus #5#6 constitutes the next two-character coefficient + % #8 is the element a of F_256. It should contain two characters. + \def\qr@testii{#2}% + \def\qr@testv{#5}% + \ifx\qr@testii\qr@relax + % #1 contains the whole string. + % Now if #5 is also \relax, that means the two strings started off with equal lengths. + % If, however, #5 is not \relax, that means the second string was longer than the first, a problem. + \ifx\qr@testv\qr@relax + %No problem. We are done. + \FX@subtract@saveresult(#1#2#3#4)% %We keep the #2#3#4 to be sure we have all three relax-es to strip off. + \else + %Problem! The second string was longer than the first. + %This usually indicates the end of the long division process. + \FX@subtract@failedtrue + \def\FX@subtraction@result{}% + \fi + \else + % There is still a coefficient to manipulate in #2#3. + % Check whether #5 contains anything. + \ifx\qr@testv\qr@relax + % No, #5 is empty. We are done. "#2#3#4" contains the remainder of the first string, + % which we append untouched and then strip off the three \relax-es. + \FX@subtract@saveresult(#1#2#3#4)% + \else + % Yes, #5#6 still has something to XOR. Do the task. + \F@multiply{#5#6}{#8}% Multiply by the factor 'a'. + \F@addstrings{#2#3}{\F@result}% Subtract. (We're in characteristic two, so adding works.) + \edef\qr@argument{(#1\F@result,#4)(#7)(#8)}% + \xa\FX@subtract@recursive\qr@argument% + \fi + \fi +}% + +\def\FX@subtract@saveresult(#1\relax\relax\relax){% + %Strips off the three extra '\relax'es at the end. + \def\FX@subtraction@result{#1}% +}% + +\def\FX@creategeneratorpolynomial#1{% + % #1 = n, the number of error codewords desired. + % We need to create \prod_{j=0}^{n-1} (x-2^j). + \edef\FX@generator@degree{#1}% + \def\FX@generatorpolynomial{01}% Initially, set it equal to 1. + \setcounter{qr@i}{0}% + \FX@creategenerator@recursive% + %The result is now stored in \FX@generatorpolynomial +}% + +\def\FX@creategenerator@recursive{% + % \c@qr@i contains the current value of i. + % \FX@generatorpolynomial contains the current polynomial f(x), + % which should be a degree-i polynomial + % equal to \prod_{j=0}^{i-1} (x-2^j). + % (If i=0, then \FX@generatorpolynomial should be 01.) + % This recursion step should multiply the existing polynomial by (x-2^i), + % increment i by 1, and check whether we're done or not. + \edef\qr@summandA{\FX@generatorpolynomial 00}% This is f(x) * x + \edef\qr@summandB{00\FX@generatorpolynomial}% This is f(x), with a 0x^{i+1} in front. + \F@twotothe{\theqr@i}% + \edef\qr@theconstant{\F@result}% + \FX@subtractphase{\qr@summandA}{\qr@summandB}{\qr@theconstant}% + %This calculates \qr@summandA + \qr@theconstant * \qr@summandB + %and stores the result in \FX@subtraction@result + \edef\FX@generatorpolynomial{\FX@subtraction@result}% + \stepcounter{qr@i}% + \xa\ifnum\FX@generator@degree=\c@qr@i\relax% + %We just multiplied by (x-2^{n-1}), so we're done. + \relax% + \else% + %We need to do this again! + \xa% + \FX@creategenerator@recursive% + \fi% +}% + +\def\FX@generate@errorbytes#1#2{% + % #1 = datastream in hex + % #2 = number of error correction bytes requested + \edef\qr@numerrorbytes{#2}% + \xa\FX@creategeneratorpolynomial\xa{\qr@numerrorbytes}% + \edef\FX@numerator{#1}% + \qr@for \i = 1 to \qr@numerrorbytes by 1% + {\g@addto@macro\FX@numerator{00}}% %One error byte means two hex codes. + \FX@polynomialdivide{\FX@numerator}{\FX@generatorpolynomial}% + \edef\FX@errorbytes{\qr@theremainder}% +}% +\newif\ifqr@versionmodules + +\def\qr@level@char#1{% + \xa\ifcase#1 + M\or L\or H\or Q\fi}% + +\newif\ifqr@versiongoodenough +\def\qr@choose@best@version#1{% + % \qr@desiredversion = user-requested version + % \qr@desiredlevel = user-requested error-correction level + \edef\qr@plaintext{#1}% + \qr@getstringlength{\qr@plaintext}% + % + %Run double loop over levels and versions, looking for + %the smallest version that can contain our data, + %and then choosing the best error-correcting level at that version, + %subject to the level being at least as good as the user desires. + \global\qr@versiongoodenoughfalse% + \gdef\qr@bestversion{0}% + \gdef\qr@bestlevel{0}% + \ifnum\qr@desiredversion=0\relax + \qr@a=1\relax + \else + \qr@a=\qr@desiredversion\relax + \fi + \qr@for \i=\qr@a to 40 by 1 + {\edef\qr@version{\the\i}% + \global\qr@versiongoodenoughfalse + \qr@for \j=0 to 3 by 1% + {%First, we map {0,1,2,3} to {1,0,4,3}, so that we loop through {M,L,H,Q} + %in order of increasing error-correction capabilities. + \qr@a = \j\relax + \divide \qr@a by 2\relax + \multiply \qr@a by 4\relax + \advance \qr@a by 1\relax + \advance \qr@a by -\j\relax + \edef\qr@level{\the\qr@a}% + \ifnum\qr@desiredlevel=\qr@a\relax + \global\qr@versiongoodenoughtrue + \fi + \ifqr@versiongoodenough + \qr@calculate@capacity{\qr@version}{\qr@level}% + \xa\xa\xa\ifnum\xa\qr@truecapacity\xa<\qr@stringlength\relax + %Too short + \relax + \else + %Long enough! + \xdef\qr@bestversion{\qr@version}% + \xdef\qr@bestlevel{\qr@level}% + \global\i=40% + \fi + \fi + }% + }% + \edef\qr@version{\qr@bestversion}% + \edef\qr@level{\qr@bestlevel}% + \xa\ifnum\qr@desiredversion>0\relax + \ifx\qr@bestversion\qr@desiredversion\relax + %No change from desired version. + \else + %Version was increased + \message{^^J}% + \fi + \fi + \ifx\qr@bestlevel\qr@desiredlevel\relax + %No change in level. + \else + \message{^^J}% + \fi +}% + +\def\qr@calculate@capacity#1#2{% + \edef\qr@version{#1}% + \edef\qr@level{#2}% + %Calculate \qr@size, the number of modules per side. + % The formula is 4\qr@version+17. + \qr@a=\qr@version\relax% + \multiply\qr@a by 4\relax% + \advance\qr@a by 17\relax% + \edef\qr@size{\the\qr@a}% + % + % Calculate \qr@k, which governs the number of alignment patterns. + % The alignment patterns lie in a kxk square, except for 3 that are replaced by finding patterns. + % The formula is 2 + floor( \qr@version / 7 ), except that k=0 for version 1. + \xa\ifnum\qr@version=1\relax% + \def\qr@k{0}% + \else% + \qr@a=\qr@version\relax + \divide \qr@a by 7\relax + \advance\qr@a by 2\relax + \edef\qr@k{\the\qr@a}% + \fi% + % + %Calculate number of function pattern modules. + %This consists of the three 8x8 finder patterns, the two timing strips, and the (k^2-3) 5x5 alignment patterns. + %The formula is 160+2n+25(k^2-3)-10(k-2), unless k=0 in which case we just have 160+2n. + \qr@a=\qr@size\relax + \multiply\qr@a by 2\relax + \advance\qr@a by 160\relax + \xa\ifnum\qr@k=0\relax\else + %\qr@k is nonzero, hence at least 2, so we continue to add 25(k^2-3)-10(k-2). + \qr@b=\qr@k\relax + \multiply\qr@b by \qr@k\relax + \advance\qr@b by -3\relax + \multiply\qr@b by 25\relax + \advance\qr@a by \qr@b\relax + \qr@b=\qr@k\relax + \advance\qr@b by -2\relax + \multiply\qr@b by 10\relax + \advance\qr@a by -\qr@b\relax + \fi + \edef\qr@numfunctionpatternmodules{\the\qr@a}% + % + %Calculate the number of version modules, either 36 or 0. + \xa\ifnum\qr@version>6\relax + \qr@versionmodulestrue + \def\qr@numversionmodules{36}% + \else + \qr@versionmodulesfalse + \def\qr@numversionmodules{0}% + \fi + % + %Now calculate the codeword capacity and remainder bits. + %Take n^2 modules, subtract all those dedicated to finder patterns etc., format information, and version information, + %and what's left is the number of bits we can play with. + %The number of complete bytes is \qr@numdatacodewords; + %the leftover bits are \qr@numremainderbits. + \qr@a=\qr@size\relax + \multiply \qr@a by \qr@size\relax + \advance \qr@a by -\qr@numfunctionpatternmodules\relax + \advance \qr@a by -31\relax% % There are 31 format modules. + \advance \qr@a by -\qr@numversionmodules\relax + \qr@b=\qr@a\relax + \divide \qr@a by 8\relax + \edef\qr@numdatacodewords{\the\qr@a}% + \multiply\qr@a by 8\relax + \advance \qr@b by -\qr@a\relax + \edef\qr@numremainderbits{\the\qr@b}% + % + %The size of the character count indicator also varies by version. + %There are only two options, so hardcoding seems easier than expressing these functionally. + \xa\ifnum\qr@version<10\relax + \def\qr@charactercountbytes@byte{1}% + \def\qr@charactercountbits@byte{8}% + \else + \def\qr@charactercountbytes@byte{2}% + \def\qr@charactercountbits@byte{16}% + \fi + % + %Now we call on the table, from the QR specification, + %of how many blocks to divide the message into, and how many error bytes each block gets. + %This affects the true capacity for data, which we store into \qr@totaldatacodewords. + % The following macro sets \qr@numblocks and \qr@num@eccodewords + % based on Table 9 of the QR specification. + \qr@settableix + \qr@a = -\qr@numblocks\relax + \multiply \qr@a by \qr@num@eccodewords\relax + \advance\qr@a by \qr@numdatacodewords\relax + \edef\qr@totaldatacodewords{\the\qr@a}% + \advance\qr@a by -\qr@charactercountbytes@byte\relax%Subtract character count + \advance\qr@a by -1\relax% Subtract 1 byte for the 4-bit mode indicator and the 4-bit terminator at the end. + \edef\qr@truecapacity{\the\qr@a}% +} + +\def\qr@setversion#1#2{% + % #1 = version number, an integer between 1 and 40 inclusive. + % #2 = error-correction level, as an integer between 0 and 3 inclusive. + % 0 = 00 = M + % 1 = 01 = L + % 2 = 10 = H + % 3 = 11 = Q + % This macro calculates and sets a variety of global macros and/or counters + % storing version information that is used later in construction the QR code. + % Thus \qr@setversion should be called every time! + % + \edef\qr@version{#1}% + \edef\qr@level{#2}% + % + \qr@calculate@capacity{\qr@version}{\qr@level}% + %The capacity-check code sets the following: + % * \qr@size + % * \qr@k + % * \ifqr@versionmodules + % * \qr@numversionmodules + % * \qr@numdatacodewords + % * \qr@numremainderbits + % * \qr@charactercountbits@byte + % * \qr@charactercountbytes@byte + % * \qr@numblocks (via \qr@settableix) + % * \qr@num@eccodewords (via \qr@settableix) + % * \qr@totaldatacodewords + % + % The alignment patterns' square is 7 modules in from each edge. + % They are spaced "as evenly as possible" with an even number of modules between each row/column, + % unevenness in division being accommodated by making the first such gap smaller. + % The formula seems to be + % general distance = 2*round((n-13)/(k-1)/2+0.25) + % = 2*floor((n-13)/(k-1)/2+0.75) + % = 2*floor( (2*(n-13)/(k-1)+3) / 4 ) + % = (((2*(n-13)) div (k-1) + 3 ) div 4 ) * 2 + % first distance = leftovers + % The 0.25 is to accommodate version 32, which is the only time we round down. + % Otherwise a simple 2*ceiling((n-13)/(k-1)/2) would have sufficed. + % + \qr@a = \qr@size\relax + \advance\qr@a by -13\relax + \multiply\qr@a by 2\relax + \qr@b = \qr@k\relax + \advance \qr@b by -1\relax + \divide\qr@a by \qr@b\relax + \advance\qr@a by 3\relax + \divide\qr@a by 4\relax + \multiply\qr@a by 2\relax + \edef\qr@alignment@generalskip{\the\qr@a}% + % + %Now set \qr@alignment@firstskip to (\qr@size-13)-(\qr@k-2)*\qr@alignment@generalskip % + \qr@a = \qr@k\relax + \advance\qr@a by -2\relax + \multiply\qr@a by -\qr@alignment@generalskip\relax + \advance\qr@a by \qr@size\relax + \advance\qr@a by -13\relax + \edef\qr@alignment@firstskip{\the\qr@a}% + % + % + % + % Our \qr@totaldatacodewords bytes of data are broken up as evenly as possible + % into \qr@numblocks datablocks; some may be one byte longer than others. + % We set \qr@shortblock@size to floor(\qr@totaldatacodewords / \qr@numblocks) + % and \qr@numlongblocks to mod(\qr@totaldatacodewords , \qr@numblocks). + \qr@a=\qr@totaldatacodewords\relax + \divide\qr@a by \qr@numblocks\relax + \edef\qr@shortblock@size{\the\qr@a}% + \multiply\qr@a by -\qr@numblocks\relax + \advance\qr@a by \qr@totaldatacodewords\relax + \edef\qr@numlongblocks{\the\qr@a}% + % + %Set \qr@longblock@size to \qr@shortblock@size+1. + \qr@a=\qr@shortblock@size\relax + \advance\qr@a by 1\relax + \edef\qr@longblock@size{\the\qr@a}% + % + %Set \qr@numshortblocks to \qr@numblocks - \qr@numlongblocks + \qr@b=\qr@numblocks\relax + \advance\qr@b by -\qr@numlongblocks\relax + \edef\qr@numshortblocks{\the\qr@b}% +}% + +\def\qr@settableix@int(#1,#2){% + \edef\qr@numblocks{#1}% + \edef\qr@num@eccodewords{#2}% +}% + +\def\qr@settableix{% +\xa\ifcase\qr@level\relax + %00: Level 'M', medium error correction + \edef\qr@tempdata{(% + \ifcase\qr@version\relax + \relax %There is no version 0. + \or1,10% + \or1,16% + \or1,26% + \or2,18% + \or2,24% + \or4,16% + \or4,18% + \or4,22% + \or5,22% + \or5,26% + \or5,30% + \or8,22% + \or9,22% + \or9,24% + \or10,24% + \or10,28% + \or11,28% + \or13,26% + \or14,26% + \or16,26% + \or17,26% + \or17,28% + \or18,28% + \or20,28% + \or21,28% + \or23,28% + \or25,28% + \or26,28% + \or28,28% + \or29,28% + \or31,28% + \or33,28% + \or35,28% + \or37,28% + \or38,28% + \or40,28% + \or43,28% + \or45,28% + \or47,28% + \or49,28% + \fi)}% +\or + %01: Level 'L', low error correction + \edef\qr@tempdata{% + (\ifcase\qr@version\relax + \relax %There is no version 0. + \or 1,7% + \or 1,10% + \or 1,15% + \or 1,20% + \or 1,26% + \or 2,18% + \or 2,20% + \or 2,24% + \or 2,30% + \or 4,18% + \or 4,20% + \or 4,24% + \or 4,26% + \or 4,30% + \or 6,22% + \or 6,24% + \or 6,28% + \or 6,30% + \or 7,28% + \or 8,28% + \or 8,28% + \or 9,28% + \or 9,30% + \or 10,30% + \or 12,26% + \or 12,28% + \or 12,30% + \or 13,30% + \or 14,30% + \or 15,30% + \or 16,30% + \or 17,30% + \or 18,30% + \or 19,30% + \or 19,30% + \or 20,30% + \or 21,30% + \or 22,30% + \or 24,30% + \or 25,30% + \fi)}% +\or + %10: Level 'H', high error correction + \edef\qr@tempdata{(% + \ifcase\qr@version\relax + \relax %There is no version 0. + \or1,17% + \or1,28% + \or2,22% + \or4,16% + \or4,22% + \or4,28% + \or5,26% + \or6,26% + \or8,24% + \or8,28% + \or11,24% + \or11,28% + \or16,22% + \or16,24% + \or18,24% + \or16,30% + \or19,28% + \or21,28% + \or25,26% + \or25,28% + \or25,30% + \or34,24% + \or30,30% + \or32,30% + \or35,30% + \or37,30% + \or40,30% + \or42,30% + \or45,30% + \or48,30% + \or51,30% + \or54,30% + \or57,30% + \or60,30% + \or63,30% + \or66,30% + \or70,30% + \or74,30% + \or77,30% + \or81,30% + \fi)}% +\or + %11: Level 'Q', quality error correction + \edef\qr@tempdata{(% + \ifcase\qr@version\relax + \relax %There is no version 0. + \or1,13% + \or1,22% + \or2,18% + \or2,26% + \or4,18% + \or4,24% + \or6,18% + \or6,22% + \or8,20% + \or8,24% + \or8,28% + \or10,26% + \or12,24% + \or16,20% + \or12,30% + \or17,24% + \or16,28% + \or18,28% + \or21,26% + \or20,30% + \or23,28% + \or23,30% + \or25,30% + \or27,30% + \or29,30% + \or34,28% + \or34,30% + \or35,30% + \or38,30% + \or40,30% + \or43,30% + \or45,30% + \or48,30% + \or51,30% + \or53,30% + \or56,30% + \or59,30% + \or62,30% + \or65,30% + \or68,30% + \fi)}% +\fi +\xa\qr@settableix@int\qr@tempdata +}% +\define@key{qr}{version}{\edef\qr@desiredversion{#1}}% +\define@key{qr}{level}{\qr@setlevel{#1}}% +\define@key{qr}{height}{\qr@setheight{#1}}% +\define@boolkey{qr}[qr@]{tight}[true]{}% %This creates \ifqr@tight and initializes it to true. +\define@boolkey{qr}[qr@]{padding}[true]{\ifqr@padding\qr@tightfalse\else\qr@tighttrue\fi}% %Define 'padding' as antonym to 'tight' + +\def\@qr@M{M}\def\@qr@z{0}% +\def\@qr@L{L}\def\@qr@i{1}% +\def\@qr@H{H}\def\@qr@ii{2}% +\def\@qr@Q{Q}\def\@qr@iii{3}% +\def\qr@setlevel#1{% + \edef\qr@level@selected{#1}% + \ifx\qr@level@selected\@qr@M + \edef\qr@desiredlevel{0}% + \fi + \ifx\qr@level@selected\@qr@L + \edef\qr@desiredlevel{1}% + \fi + \ifx\qr@level@selected\@qr@H + \edef\qr@desiredlevel{2}% + \fi + \ifx\qr@level@selected\@qr@Q + \edef\qr@desiredlevel{3}% + \fi + \ifx\qr@level@selected\@qr@z + \edef\qr@desiredlevel{0}% + \fi + \ifx\qr@level@selected\@qr@i + \edef\qr@desiredlevel{1}% + \fi + \ifx\qr@level@selected\@qr@ii + \edef\qr@desiredlevel{2}% + \fi + \ifx\qr@level@selected\@qr@iii + \edef\qr@desiredlevel{3}% + \fi +}% + +\def\qr@setheight#1{% + \setlength{\qr@desiredheight}{#1}% +}% + +\newcommand\qrset[1]{% + \setkeys{qr}{#1}% +} + +\qrset{version=0, level=0, tight} +\newif\ifqr@starinvoked% +\def\qrcode{\@ifstar\qrcode@star\qrcode@nostar}% +\def\qrcode@star{\qr@starinvokedtrue\qrcode@i}% +\def\qrcode@nostar{\qr@starinvokedfalse\qrcode@i}% + +\newcommand\qrcode@i[1][]{% + \begingroup% + \ifqr@starinvoked% + \qr@hyperlinkfalse% + \fi% + \setkeys{qr}{#1}% + \bgroup\qr@verbatimcatcodes\qr@setescapedspecials\qrcode@in}% + +\def\qrcode@in#1{\xdef\qr@texttoencode{#1}\egroup\qrcode@int\endgroup}% + +\def\qrcode@hyperwrapper@hyperref{\href{\qr@texttoencode}}% +\def\qrcode@hyperwrapper@nohyperref{\relax}% + +\AtBeginDocument{% + \@ifpackageloaded{hyperref}% + {\global\let\qrcode@hyperwrapper=\qrcode@hyperwrapper@hyperref}% + {\global\let\qrcode@hyperwrapper=\qrcode@hyperwrapper@nohyperref}% +}% + +\def\qrcode@int{% + \message{^^J^^J^^J}% + %First, choose the version and level. + %Recall that \qr@choose@best@version sets \qr@version and \qr@level. + \xa\qr@choose@best@version\xa{\qr@texttoencode}% + \qr@setversion{\qr@version}{\qr@level}% + % + \ifqr@hyperlink% + \let\qrcode@wrapper=\qrcode@hyperwrapper% + \else% + \let\qrcode@wrapper=\relax% + \fi% + % + %Next, check whether we have already encoded this text at this version + %and level. + \qrcode@wrapper{% + \xa\ifx\csname qr@savedbinarymatrix@\qr@texttoencode @\qr@version @\qr@level\endcsname + \relax% + %This text has not yet been encoded. + \qrcode@int@new% + \else + %This text has already been encoded! + \ifqr@forget@mode + %In 'forget' mode, we deliberately recalculate anyway. + \qrcode@int@new% + \else + \qrcode@int@remember% + \fi + \fi% + }% +}% + +\def\qrcode@int@new{% + \qr@createsquareblankmatrix{newqr}{\qr@size}% + \qr@placefinderpatterns{newqr}% + \qr@placetimingpatterns{newqr}% + \qr@placealignmentpatterns{newqr}% + \qr@placedummyformatpatterns{newqr}% + \qr@placedummyversionpatterns{newqr}% + \ifqr@draft@mode + \message{^^J}% + \relax% Draft mode---don't load any data or do any work. Also don't save! + \def\qr@format@square{\qr@black}% + \def\qr@blank{\qr@white}% + \fboxsep=-\fboxrule% + \fbox{\qr@printmatrix{newqr}}% + \else + \message{^^J}% + \xa\qr@encode@binary\xa{\qr@texttoencode}% + \qr@splitcodetextintoblocks + \qr@createerrorblocks + \qr@interleave + \message{^^J}% + \qr@writeremainderbits{newqr}% + \qr@chooseandapplybestmask{newqr}% + \qr@decimaltobinary[2]{\qr@level@binary}{\qr@level}% + \qr@decimaltobinary[3]{\qr@mask@binary}{\qr@mask@selected}% + \edef\qr@formatstring{\qr@level@binary\qr@mask@binary}% + \message{^^J}% + \message{^^J}% + \message{^^J}% + % + %Also save the binary version into the aux file, for use in later runs. + \message{^^J}% + \message{^^J}% + \fi + \message{^^J}% +}% +\def\qrcode@int@remember{% + %This text has already been encoded, + %so we just copy it from the saved binary string. + \message{^^J}% + \xa\qr@printsavedbinarymatrix\xa{\csname qr@savedbinarymatrix@\qr@texttoencode @\qr@version @\qr@level\endcsname}% + % + % Now this still might need to be written to the aux file. + % + \xa\ifx\csname qr@savedflag@\qr@texttoencode @\qr@version @\qr@level\endcsname\@qr@TRUE + %Okay, this has already been written to aux file. + %Do nothing. + \relax% + \else% + %This has NOT been written to the aux file yet. + %We need to do so now. + \xa\qr@writebinarymatrixtoauxfile\xa{\csname qr@savedbinarymatrix@\qr@texttoencode @\qr@version @\qr@level\endcsname}% + \fi% +}% + +\def\qr@matrixtobinary#1{% + \def\qr@binarymatrix@result{}% + \bgroup + \def\qr@black{1}% + \def\qr@white{0}% + \def\qr@blank{0}% + \def\qr@black@fixed{1}% + \def\qr@white@fixed{0}% + \def\qr@black@format{1}% + \def\qr@white@format{0}% + % + \qr@for \i = 1 to \qr@size by 1% + {\qr@for \j = 1 to \qr@size by 1% + {\edef\qr@theentry{\qr@matrixentry{#1}{\the\i}{\the\j}}% + \xa\g@addto@macro\xa\qr@binarymatrix@result\xa{\qr@theentry}% + }% + }% + \egroup% +}% + +\def\qr@sanitize@output#1{% + %Read through ASCII text '#1' and escape backslashes and braces + \def\qr@sanitized@result{}% + \edef\qr@argument{(#1\relax\relax\relax)}% + \xa\qr@sanitize@output@int\qr@argument% +} + +\def\qr@sanitize@output@int(#1#2){% + % #1 = first character + % #2 = rest of output, including terminator + \edef\qr@testi{#1}% + \ifx\qr@testi\qr@relax + % Done. + \let\qr@next=\relax + \else + \ifx\qr@testi\qr@otherrightbrace + \edef\qr@sanitized@result{\qr@sanitized@result\qr@otherbackslash}% + \else\ifx\qr@testi\qr@otherleftbrace + \edef\qr@sanitized@result{\qr@sanitized@result\qr@otherbackslash}% + \else\ifx\qr@testi\qr@otherbackslash + \edef\qr@sanitized@result{\qr@sanitized@result\qr@otherbackslash}% + \fi + \fi + \fi + \edef\qr@sanitized@result{\qr@sanitized@result#1}% + \def\qr@next{\qr@sanitize@output@int(#2)}% + \fi + \qr@next +} + +\def\@qr@TRUE{TRUE}% +\def\qr@writebinarymatrixtoauxfile#1{% + \qr@sanitize@output{\qr@texttoencode}% + \edef\qr@theargument{{\qr@sanitized@result}{\qr@version}{\qr@level}{#1}}% + \xa\write\xa\@auxout\xa{\xa\string\xa\qr@savematrix\qr@theargument}% + % + % Now set a flag, so we don't write this again. + \xa\gdef\csname qr@savedflag@\qr@texttoencode @\qr@version @\qr@level\endcsname{TRUE}% +}% + +\gdef\qr@dummyqrsavedefinition{}% +\begingroup + \catcode`\#=12\relax + \catcode`\<=1\relax + \catcode`\{=12\relax + \catcode`\>=2\relax + \catcode`\}=12\relax + \catcode`\|=0\relax + \catcode`\\=12|relax + |gdef|qr@dummyqrsavedefinition<% + \ifx\qr@savematrix\@undefined% + \def\qr@savematrix{\begingroup\let\do\@makeother\dospecials\catcode`\{=1\catcode`\}=2\relax + \qr@savematrix@int}% + \def\qr@savematrix@int#1#2#3#4{\endgroup}% + \fi% + > +|endgroup + +\edef\qr@argument{(\qr@dummyqrsavedefinition)}% +\xa\write\xa\@auxout\xa{\qr@dummyqrsavedefinition}% + +\def\qr@savematrix{\bgroup\qr@verbatimcatcodes\qr@setescapedspecials\qr@savematrix@int}% + +\def\qr@savematrix@int#1{\xdef\qr@savedmatrix@name{#1}\egroup\qr@savematrix@int@int}% + +\def\qr@savematrix@int@int#1#2#3{% + % \qr@savedmatrix@name = encoded text + % #1 = version + % #2 = level + % #3 = binary text + \def\ds{^^J}\xa\message\xa{\ds}% + {\let\%=\qr@otherpercent + \xa\gdef\csname qr@savedbinarymatrix@\qr@savedmatrix@name @#1@#2\endcsname{#3}% + }% +}% +\endinput +%% +%% End of file `qrcode.sty'. diff --git a/tools/style/shortcuts.sty b/tools/style/shortcuts.sty index 96652b5..c16a015 100755 --- a/tools/style/shortcuts.sty +++ b/tools/style/shortcuts.sty @@ -29,11 +29,11 @@ %% Vecteurs % représentation d'un vecteur -\renewcommand{\vect}[1]{\overrightarrow{#1}} +\newcommand{\vect}[1]{\overrightarrow{#1}} % Norme d'un vecteur -\newcommand{\norme}[1]{||\vec{#1}||} +\newcommand{\norme}[1]{||\vect{#1}||} % Produit scalaire -\newcommand{\scal}[2]{\vec{#1} \cdot \vec{#2}} +\newcommand{\scal}[2]{\vect{#1} \cdot \vect{#2}} \newcommand{\vectCoord}[2]{% {\renewcommand{\arraystretch}{1}% \left(\begin{array}{c} #1 \\ #2 \end{array} \right)% @@ -41,7 +41,7 @@ } % Les complexes -\def\Ouv{$\left(\text{O}~;~\vec{u},~\vec{v}\right)$} +\def\Ouv{$\left(\text{O}~;~\vect{u},~\vect{v}\right)$} \newcommand{\e}{\mathrm{\,e\,}}% le e de l'exponentielle %\renewcommand{\i}{\mathrm{\,i\,}}% le i des complexes