diff options
author | Karl Berry <karl@freefriends.org> | 2021-04-19 21:25:21 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-04-19 21:25:21 +0000 |
commit | 3125499a8c2b497b0f964e23c53d9c9fe3fe4e58 (patch) | |
tree | 1618fa57d975d6d12cde15c8b1190c09061d033c /Master/texmf-dist/tex/luatex/optex/pkg/qrcode.opm | |
parent | f5f0b7d1217bc7ab099302a505fffcac39d41006 (diff) |
optex its own format, so directly under tex/ and doc/
git-svn-id: svn://tug.org/texlive/trunk@58918 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/optex/pkg/qrcode.opm')
-rw-r--r-- | Master/texmf-dist/tex/luatex/optex/pkg/qrcode.opm | 2707 |
1 files changed, 0 insertions, 2707 deletions
diff --git a/Master/texmf-dist/tex/luatex/optex/pkg/qrcode.opm b/Master/texmf-dist/tex/luatex/optex/pkg/qrcode.opm deleted file mode 100644 index 5df0ad2c074..00000000000 --- a/Master/texmf-dist/tex/luatex/optex/pkg/qrcode.opm +++ /dev/null @@ -1,2707 +0,0 @@ -% This is macro package used by OpTeX, see http://petr.olsak.net/optex -% qrcode.opm, Petr Olšák <petr@olsak.net>, 2020 - -% See end of the file for more information - -\_codedecl \qrcode {Macro for QR code printing <2020-05-04>} - -\_namespace{qr} - -\_newcount\.i -\_newcount\.j -\_newcount\.a -\_newcount\.b -\_newcount\.c - -\_def\.relax{\_relax}% - -\_def\.utfstring#1{\_directlua{ - local text="\_luaescapestring{#1}" - tex.print(string.format('\_pcent.2x',string.len(text))) - for i=1,string.len(text) do - tex.print(string.format('\_pcent.2x',string.byte(text,i))) - end -}} -\_def\.utfstringlen#1{\_directlua{ - tex.print(string.len("\_luaescapestring{#1}")) -}} - -\_def\.g_preface_macro#1#2{% - % #1 = macro to be appended to - % #2 = code to add - \_edef\.codeA{#2}% - \_ea\_ea\_ea\_gdef\_ea\_ea\_ea#1\_ea\_ea\_ea{\_ea\.codeA#1}% -} - -\_def\.getstringlength#1{% - \_xdef\.stringlength{\.utfstringlen{#1}}% -}% - -\_def\.for#1=#2to#3by#4#{\.forA{#1}{#2}{#3}{#4}} -\_long\_def\.forA#1#2#3#4#5{\_begingroup - {\_escapechar=`\\ % allocation of #1 as counter: - \_ea \_ifx\_csname for:\_string#1\_endcsname \_relax - \_csname newcount\_ea\_endcsname \_csname for:\_string#1\_endcsname\_fi - \_ea}\_ea\_let\_ea#1\_csname for:\_string#1\_endcsname - #1=#2% - \_def\.forB{#5\_advance#1by#4\_relax \_ea\.forC}% - \_ifnum#4>0 \_def\.forC{\_ifnum#1>#3\_relax\_else\.forB\_fi}% - \_else \_def\.forC{\_ifnum#1<#3\_relax\_else\.forB\_fi}% - \_fi - \_ifnum#4=0 \let\.forC=\_relax \_fi - \.forC \_endgroup -} - -\_def\.padatfront#1#2{% - % #1 = macro containing text to pad - % #2 = desired number of characters - % Pads a number with initial zeros. - \.getstringlength{#1}% - \.a=\.stringlength\_relax - \_advance\.a by 1\_relax - \.for \.iz = \.a to #2 by 1 - {\.g_preface_macro{#1}{0}}% -} - -\.a=-1\_relax -\_def\.savehexsymbols(#1#2){% - \_advance\.a by 1\_relax% - \_ea\_def\_csname _qr_hexchar:\_the\.a\_endcsname{#1}% - \_ea\_edef\_csname _qr_hextodecimal:#1\_endcsname{\_the\.a}% - \_ifnum\.a=15\_relax - %Done. - \_let\.next=\_relax - \_else - \_def\.next{\.savehexsymbols(#2)}% - \_fi - \.next -}% -\.savehexsymbols(0123456789abcdef\_relax\_relax)% - -\_def\.decimaltobase#1#2#3{% - % #1 = macro to store result - % #2 = decimal representation of a positive integer - % #3 = new base - \_bgroup - \_edef\.newbase{#3}% - \_gdef\.base_result{}% - \.a=#2\_relax% - \.decimaltobase_recursive% - \_xdef#1{\.base_result}% - \_egroup -} -\_def\.decimaltobase_recursive{% - \.b=\.a - \_divide\.b by \.newbase\_relax - \_multiply\.b by -\.newbase\_relax - \_advance\.b by \.a\_relax - \_divide\.a by \.newbase\_relax - \_ifnum\.b<10\_relax - \_edef\.newdigit{\_the\.b}% - \_else - \_edef\.newdigit{\_csname _qr_hexchar:\_the\.b\_endcsname}% - \_fi - \_edef\.argument{{\_noexpand\.base_result}{\.newdigit}}% - \_ea\.g_preface_macro\.argument - \_ifnum\.a=0\_relax - \_relax - \_else - \_ea\.decimaltobase_recursive - \_fi -} -\_long\_def\.xaddto#1#2{\_xdef#1{#1#2}} - -\_def\.decimaltohex[#1]#2#3{% - % #1 (opt.) = number of hex digits to create - % #2 = macro to store result - % #3 = decimal digits to convert - \.decimaltobase{#2}{#3}{16}% - \.padatfront{#2}{#1}% -} -\_def\.decimaltobinary[#1]#2#3{% - % #1 (opt.) = number of bits to create - % #2 = macro to store result - % #3 = decimal digits to convert - \.decimaltobase{#2}{#3}{2}% - \.padatfront{#2}{#1}% -} - -\.for \.iz = 0 to 15 by 1% - {% - \.decimaltohex[1]{\.hexchar}{\_the\.iz}% - \.decimaltobinary[4]{\.bits}{\_the\.iz}% - \_ea\_xdef\_csname _qr_b2h:\.bits\_endcsname{\.hexchar}% - \_ea\_xdef\_csname _qr_h2b:\.hexchar\_endcsname{\.bits}% - }% - -\_def\.binarytohex[#1]#2#3{% - % #1 (optional) = # digits desired - % #2 = macro to save to - % #3 = binary string (must be multiple of 4 bits) - \_def\.testi{#1}% - \_ifx\.testi\.relax% - %No argument specified - \_def\.desireddigits{0}% - \_else - \_def\.desireddigits{#1}% - \_fi - \_gdef\.base_result{}% - \_edef\.argument{(#3\_relax\_relax\_relax\_relax\_relax)}% - \_ea\.binarytohex_int\.argument% - \.padatfront{\.base_result}{\.desireddigits}% - \_xdef#2{\.base_result}% -} -\_def\.binarytohex_int(#1#2#3#4#5){% - % #1#2#3#4 = 4 bits - % #5 = remainder, including \_relax\_relax\_relax\_relax\_relax terminator - \_def\.testi{#1}% - \_ifx\.testi\.relax% - %Done. - \_def\.next{\_relax}% - \_else% - \_xdef\.base_result{\.base_result\_csname _qr_b2h:#1#2#3#4\_endcsname}% - \_def\.next{\.binarytohex_int(#5)}% - \_fi% - \.next% -} - -\_def\.hextobinary[#1]#2#3{% - % #1 (optional) = # bits desired - % #2 = macro to save to - % #3 = hexadecimal string - \_bgroup - \_def\.testi{#1}% - \_ifx\.testi\.relax - %No argument specified - \_def\.desireddigits{0}% - \_else - \_def\.desireddigits{#1}% - \_fi - \_gdef\.base_result{}% - \_edef\.argument{(#3\_relax\_relax)}% - \_ea\.hextobinary_int\.argument% - \.padatfront{\.base_result}{\.desireddigits}% - \_xdef#2{\.base_result}% - \_egroup -} -\_def\.hextobinary_int(#1#2){% - % #1 = hexadecimal character - % #2 = remainder, including \_relax\_relax terminator - \_def\.testii{#1}% - \_ifx\.testii\.relax - %Done. - \_def\.next{\_relax}% - \_else - \_xdef\.base_result{\.base_result\_csname _qr_h2b:#1\_endcsname}% - \_def\.next{\.hextobinary_int(#2)}% - \_fi - \.next -} - -\_def\.hextodecimal#1#2{% - \_edef\.argument{#2}% - \_ea\.a\_ea=\_ea\_number\_ea"\.argument\_relax - \_edef#1{\_the\.a}% -} - -\_def\.hextodecimal#1#2{% - % #1 = macro to store result - % #2 = hexadecimal representation of a positive integer - \_bgroup - \.a=0\_relax - \_edef\.argument{(#2\_relax)}% - \_ea\.hextodecimal_recursive\.argument% - \_xdef#1{\_the\.a}% - \_egroup -} -\_def\.hextodecimal_recursive(#1#2){% - % #1 = first hex char - % #2 = remainder - \_advance \.a by \_csname _qr_hextodecimal:#1\_endcsname\_relax% - \_edef\.testii{#2}% - \_ifx\.testii\.relax% - %Done. - \_let\.next=\_relax% - \_else - %There's at least one more digit. - \_multiply\.a by 16\_relax - \_edef\.next{\_noexpand\.hextodecimal_recursive(#2)}% - \_fi% - \.next% -} - -\_def\.storetomatrix#1#2#3#4{% - % #1 = matrix name - % #2 = row number - % #3 = column number - % #4 = value of matrix entry - \_ea\_gdef\_csname #1@#2@#3\_endcsname{#4}% -}% - -\_def\.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 - \_ea\_gdef\_csname #1@#2@#3\_ea\_endcsname\_ea{#4}% -}% - -\_def\.matrixentry#1#2#3{% - % #1 = matrix name - % #2 = row number - % #3 = column number - \_csname #1@#2@#3\_endcsname -}% - -\_def\.createsquareblankmatrix#1#2{% -% \.creatematrix{#1}% - \_ea\_gdef\_csname #1@numrows\_endcsname{#2}% - \_ea\_gdef\_csname #1@numcols\_endcsname{#2}% - \.for \.iz = 1 to #2 by 1% - {\.for \.jz = 1 to #2 by 1% - {\.storetomatrix{#1}{\_the\.iz}{\_the\.jz}{\.blank}}}% -}% - -\_def\.numberofrowsinmatrix#1{% - \_csname #1@numrows\_endcsname% -}% - -\_def\.numberofcolsinmatrix#1{% - \_csname #1@numcols\_endcsname% -}% - -\_def\.setnumberofrows#1#2{% - \_ea\_xdef\_csname #1@numrows\_endcsname{#2}% -}% - -\_def\.setnumberofcols#1#2{% - \_ea\_xdef\_csname #1@numcols\_endcsname{#2}% -}% - -\_newdimen\.desiredheight -\_newdimen\.modulesize - -\_def\.link#1#2{\_hbox{\_pdfstartlink height\_ht0 depth0pt \.border - user{/Subtype/Link/A <</Type/Action/S/URI/URI(#1)>>}\_relax #2\_pdfendlink}% -} -\_def\.border{% - \_ifcsname _qr_kv:qrborder\_endcsname attr{/C[\.kv{qrborder}] /Border[0 0 .6]}% - \_else attr{/Border[0 0 0]}% - \_fi -} - -\_def\.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 -% \.creatematrix{#1}% - \_ea\_xdef\_csname #1@numrows\_endcsname{#2}% - \_ea\_xdef\_csname #1@numcols\_endcsname{#2}% - \_gdef\.literalmatrix_tokens{#3}% - \.for \.iz = 1 to #2 by 1% - {\.for \.jz = 1 to #2 by 1% - {\_ea\.createliteralmatrix_int\_ea(\.literalmatrix_tokens)% - \.estoretomatrix{#1}{\_the\.iz}{\_the\.jz}{\.entrytext}% - }% - }% -} -\_def\.createliteralmatrix_int(#1#2){% - \_def\.entrytext{#1}% - \_gdef\.literalmatrix_tokens{#2}% -} - -\.createliteralmatrix{finderpattern}{8}{% - \.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed\.whitefixed - \.blackfixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.blackfixed\.whitefixed - \.blackfixed\.whitefixed\.blackfixed\.blackfixed\.blackfixed\.whitefixed\.blackfixed\.whitefixed - \.blackfixed\.whitefixed\.blackfixed\.blackfixed\.blackfixed\.whitefixed\.blackfixed\.whitefixed - \.blackfixed\.whitefixed\.blackfixed\.blackfixed\.blackfixed\.whitefixed\.blackfixed\.whitefixed - \.blackfixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.blackfixed\.whitefixed - \.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed\.whitefixed - \.whitefixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed\.whitefixed -}% - -\.createliteralmatrix{alignmentpattern}{5}{% - \.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed - \.blackfixed\.whitefixed\.whitefixed\.whitefixed\.blackfixed - \.blackfixed\.whitefixed\.blackfixed\.whitefixed\.blackfixed - \.blackfixed\.whitefixed\.whitefixed\.whitefixed\.blackfixed - \.blackfixed\.blackfixed\.blackfixed\.blackfixed\.blackfixed -}% - -\_def\.copymatrixentry#1#2#3#4#5#6{% - % Copy the (#2,#3) entry of matrix #1 - % to the (#5,#6) position of matrix #4. - \_ea\_ea\_ea\_global% - \_ea\_ea\_ea\_let\_ea\_ea\_csname #4@#5@#6\_endcsname - \_csname #1@#2@#3\_endcsname -}% - -\_def\.createduplicatematrix#1#2{% - % #1 = name of copy - % #2 = original matrix to be copied -% \.creatematrix{#1}% - \.for \.iz = 1 to \.numberofrowsinmatrix{#2} by 1% - {\.for \.jz = 1 to \.numberofcolsinmatrix{#2} by 1% - {\.copymatrixentry{#2}{\_the\.iz}{\_the\.jz}{#1}{\_the\.iz}{\_the\.jz}% - }% - }% - \.setnumberofrows{#1}{\.numberofrowsinmatrix{#2}}% - \.setnumberofcols{#1}{\.numberofcolsinmatrix{#2}}% -}% - -\_def\.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 counters indicating positions in the big matrix. - \.setcounter\.i{#2}% - \.for \.sourcei=1 to 8 by 1% - {\.setcounter\.j{#3}% - \.for \.sourcej=1 to 8 by 1% - {\.copymatrixentry{finderpattern}{\_the\.sourcei}{\_the\.sourcej}% - {#1}{\_the\.i}{\_the\.j}% - \.addtocounter\.j{#5}% - }% - \.addtocounter\.i{#4}% - }% -}% - -\_def\.placefinderpatterns#1{% - % #1=matrix name - \.placefinderpattern_int{#1}{1}{1}{1}{1}% - \.placefinderpattern_int{#1}{\.numberofrowsinmatrix{#1}}{1}{-1}{1}% - \.placefinderpattern_int{#1}{1}{\.numberofcolsinmatrix{#1}}{1}{-1}% -}% - -\_def\.placetimingpatterns#1{% - %Set \.endingcol to n-8. - \.a=\.size\_relax% - \_advance\.a by -8\_relax% - \_edef\.endingcol{\_the\.a}% - \.for \.jz = 9 to \.endingcol by 1% - {\_ifodd\.jz\_relax% - \.storetomatrix{#1}{7}{\_the\.jz}{\.blackfixed}% - \.storetomatrix{#1}{\_the\.jz}{7}{\.blackfixed}% - \_else% - \.storetomatrix{#1}{7}{\_the\.jz}{\.whitefixed}% - \.storetomatrix{#1}{\_the\.jz}{7}{\.whitefixed}% - \_fi% - }% -}% - -\_def\.placealignmentpattern_int#1#2#3{% - % Work on matrix #1. - % Write an alignment pattern into the matrix, centered on (#2,#3). - \.a=#2\_relax% - \_advance\.a by -2\_relax% - \.b=#3\_relax% - \_advance\.b by -2\_relax% - \.setcounter\.i{\_the\.a}% - \.for \.iz=1 to 5 by 1% - {\.setcounter\.j{\_the\.b}% - \.for \.jz=1 to 5 by 1% - {\.copymatrixentry{alignmentpattern}{\_the\.iz}{\_the\.jz}% - {#1}{\_the\.i}{\_the\.j}% - \.stepcounter\.j - }% - \.stepcounter\.i - }% -}% - -\_newifi\_ifqr_incorner% -\_def\.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 - % * \.k stores k, - % * \.alignment_firstskip stores how far between the 1st and 2nd row/col, & - % * \.alignment_generalskip stores how far between each subsequent row/col. - \_ea\_ifnum\.k>0\_relax - %There will be at least one alignment pattern. - %N.B. k cannot equal 1. - \_ea\_ifnum\.k=2\_relax - % 2*2-3 = exactly 1 alignment pattern. - \.a=7\_relax - \_advance\.a by \.alignment_firstskip\_relax - \_xdef\.targetii{\_the\.a}% - \.placealignmentpattern_int{#1}{\.targetii}{\.targetii}% - \_else - % k is at least 3, so the following loops should be safe. - \_xdef\.targetii{7}% - \.for \.ii = 1 to \.k by 1% - {\_ifcase\.ii\_relax% - \_relax% \.ii should never equal 0. - \_or - \_xdef\.targetii{7}% If \.ii = 1, we start in row 7. - \_or - %If \.ii = 2, we add the firstskip. - \.a=\.targetii\_relax% - \_advance\.a by \.alignment_firstskip\_relax% - \_xdef\.targetii{\_the\.a}% - \_else - %If \.ii>2, we add the generalskip. - \.a=\.targetii\_relax% - \_advance\.a by \.alignment_generalskip\_relax% - \_xdef\.targetii{\_the\.a}% - \_fi - \.for \.jj = 1 to \.k by 1% - {\_ifcase\.jj\_relax% - \_relax% \.jj should never equal 0. - \_or - \_xdef\.targetjj{7}% If \.jj=1, we start in row 7. - \_or - %If \.jj=2, we add the firstskip. - \.a=\.targetjj\_relax% - \_advance\.a by \.alignment_firstskip% - \_xdef\.targetjj{\_the\.a}% - \_else - %If \.jj>2, we add the generalskip. - \.a=\.targetjj\_relax% - \_advance\.a by \.alignment_generalskip% - \_xdef\.targetjj{\_the\.a}% - \_fi - \.incornerfalse% - \_ifnum\.ii=1\_relax - \_ifnum\.jj=1\_relax - \.incornertrue - \_else - \_ifnum\.k=\.jj\_relax - \.incornertrue - \_fi - \_fi - \_else - \_ea\_ifnum\.k=\.ii\_relax - \_ifnum\.jj=1\_relax - \.incornertrue - \_fi - \_fi - \_fi - \_ifqr_incorner - \_relax - \_else - \.placealignmentpattern_int{#1}{\.targetii}{\.targetjj}% - \_fi - }% ends \.for \.jj - }% ends \.for \.ii - \_fi - \_fi -}% - -\_def\.placedummyformatpatterns#1{% - \.for \.jz = 1 to 9 by 1% - {\_ifnum\.jz=7\_relax% - \_else% - \.storetomatrix{#1}{9}{\_the\.jz}{\.formatsquare}% - \.storetomatrix{#1}{\_the\.jz}{9}{\.formatsquare}% - \_fi% - }% - \.setcounter\.j{\.size}% - \.for \.jz = 1 to 8 by 1% - {\.storetomatrix{#1}{9}{\_the\.j}{\.formatsquare}% - \.storetomatrix{#1}{\_the\.j}{9}{\.formatsquare}% - \.addtocounter\.j{-1}% - }% - %Now go back and change the \.formatsquare in (n-8,9) to \.blackfixed. - \.addtocounter\.j{1}% - \.storetomatrix{#1}{\_the\.j}{9}{\.blackfixed}% -}% - -\_def\.placedummyversionpatterns#1{% - \_ea\_ifnum\.version>6\_relax - %Must include version information. - \_global\.i=\.size% - \_global\_advance\.i by -10\_relax% - \.for \.iz = 1 to 3 by 1% - {\.for \.jz = 1 to 6 by 1% - {\.storetomatrix{#1}{\_the\.i}{\_the\.jz}{\.formatsquare}% - \.storetomatrix{#1}{\_the\.jz}{\_the\.i}{\.formatsquare}% - }% - \.stepcounter\.i - }% - \_fi -}% - -\_def\.writebit(#1#2)#3{% - % #3 = matrix name - % (qr_i,qr_j) = position to write in (counters) - % #1 = bit to be written - % #2 = remaining bits plus '\_relax' as an end-of-file marker - \_edef\.datatowrite{#2}% - \_ifnum#1=1 - \.storetomatrix{#3}{\_the\.i}{\_the\.j}{\.black}% - \_else - \.storetomatrix{#3}{\_the\.i}{\_the\.j}{\.white}% - \_fi -}% - -\_newifi\_ifqr_rightcol -\_newifi\_ifqr_goingup - -\_def\.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\.i{\.numberofrowsinmatrix{#1}}% - \.setcounter\.j{\.numberofcolsinmatrix{#1}}% - \.rightcoltrue - \.goinguptrue - \_edef\.argument{{#1}(#2\_relax\_relax\_relax)}% - \_ea\.writedata_hex_recursive\.argument% -}% - -\_def\.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 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\.testii{#2}% - \_ifx\.testii\.relax% - % #2 is \_relax, so there is nothing more to write. - \_relax - \_let\.go=\_relax - \_else - % #2 is not \_relax, so there is another byte to write. - \.hextobinary[8]{\.bytetowrite}{#2#3}% - \_xdef\.datatowrite{\.bytetowrite\_relax}% %Add terminating "\_relax" - \.writedata_recursive{#1}% %This function actually writes the 8 bits. - \_edef\.argument{{#1}(#4)}% - \_ea\_def\_ea\.go\_ea{\_ea\.writedata_hex_recursive\.argument}% %Call self to write the next bit. - \_fi - \.go -}% - -\_def\.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\.i{\.numberofrowsinmatrix{#1}}% - \.setcounter\.j{\.numberofcolsinmatrix{#1}}% - \.rightcoltrue - \.goinguptrue - \_edef\.datatowrite{#2\_relax}% - \.writedata_recursive{#1}% -}% - -\_def\.iblank{\.blank}% - -\_def\.writedata_recursive#1{% - % #1 = matrix name - % (qr_i,qr_j) = position to write in (counters) - % \.datatowrite contains the bits to be written, plus '\_relax' as an end-of-file marker - \_ea\_let\_ea\.squarevalue\_csname #1@\_the\.i @\_the\.j\_endcsname% - \_ifx\.squarevalue\.iblank - %Square is blank, so write data in it. - \_ea\.writebit\_ea(\.datatowrite){#1}% - %The \.writebit macro not only writes the first bit of \.datatowrite into the matrix, - %but also removes the bit from the 'bitstream' of \.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\.j{-1}% - \.rightcolfalse - \_else - %If we're in the left-hand column, things are harder. - \_ifqr_goingup - %First, suppose we're going upwards. - \_ifnum\.i>1\_relax% - %If we're not in the first row, things are easy. - %We move one to the right and one up. - \.addtocounter\.j{1}% - \.addtocounter\.i{-1}% - \.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\.j{-1}% - \.goingupfalse - \.rightcoltrue - \_fi - \_else - %Now, suppose we're going downwards. - \_ea\_ifnum\.size>\.i\_relax% - %If we're not yet in the bottom row, things are easy. - %We move one to the right and one down. - \.addtocounter\.j{1}% - \.addtocounter\.i{1}% - \.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\.j{-1}% - \.rightcoltrue - \.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\.j=7\_relax% - \.setcounter\.j{6}% - \_fi - \_fi - %Now check whether there are any more bits to write. - \_ifx\.datatowrite\.relax - % \.datatowrite is just `\_relax', so we're done. - \_let\.nexttoken=\_relax - \_relax - \_else - % Write some more! - \_def\.nexttoken{\.writedata_recursive{#1}}% - \_fi - \.nexttoken -}% - -\_def\.writeremainderbits#1{% - % #1 = name of a matrix that has been prepared and partly filled. - % (qr_i,qr_j) = position to write in counters - \_ea\_ifnum\.numremainderbits>0\_relax - \_def\.datatowrite{}% - \.for \.iz = 1 to \.numremainderbits by 1% - {\.xaddto{\.datatowrite}{0}}% - \.xaddto{\.datatowrite}{\_relax}% terminator - \.writedata_recursive{#1}% - \_fi -}% - -\_newifi\_ifqr_cellinmask - -\_def\.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\.maskselection{#1}% - \_ea\_ifcase\.maskselection\_relax - %Case 0: checkerboard - \_def\.parsemaskingfunction{% - % Compute mod(\themaski+\themaskj,2)% - \.a=\.maski% - \_advance\.a by \.maskj% - \.b=\.a% - \_divide\.b by 2% - \_multiply\.b by 2% - \_advance\.a by -\.b% - \_edef\.maskfunctionresult{\_the\.a}% - }% - \_or - %Case 1: horizontal stripes - \_def\.parsemaskingfunction{% - % Compute mod(\themaski,2)% - \_ifodd\.maski\_relax% - \_def\.maskfunctionresult{1}% - \_else% - \_def\.maskfunctionresult{0}% - \_fi% - }% - \_or - %Case 2: vertical stripes - \_def\.parsemaskingfunction{% - % Compute mod(\themaskj,3)% - \.a=\.maskj% - \_divide\.a by 3% - \_multiply\.a by 3% - \_advance\.a by -\.maskj% - \_edef\.maskfunctionresult{\_the\.a}% - }% - \_or - %Case 3: diagonal stripes - \_def\.parsemaskingfunction{% - % Compute mod(\themaski+\themaskj,3)% - \.a=\.maski% - \_advance\.a by \.maskj% - \.b=\.a% - \_divide\.b by 3% - \_multiply\.b by 3% - \_advance\.b by -\.a% - \_edef\.maskfunctionresult{\_the\.b}% - }% - \_or - %Case 4: wide checkerboard - \_def\.parsemaskingfunction{% - % Compute mod(floor(\themaski/2) + floor(\themaskj/3),2) % - \.a=\.maski% - \_divide\.a by 2% - \.b=\.maskj% - \_divide\.b by 3% - \_advance\.a by \.b% - \.b=\.a% - \_divide\.a by 2% - \_multiply\.a by 2% - \_advance\.a by -\.b% - \_edef\.maskfunctionresult{\_the\.a}% - }% - \_or - %Case 5: quilt - \_def\.parsemaskingfunction{% - % Compute mod(\themaski*\themaskj,2) + mod(\themaski*\themaskj,3) % - \.a=\.maski% - \_multiply\.a by \.maskj% - \.b=\.a% - \.c=\.a% - \_divide\.a by 2% - \_multiply\.a by 2% - \_advance\.a by -\.c% (result will be -mod(i*j,2), which is negative.) - \_divide\.b by 3% - \_multiply\.b by 3% - \_advance\.b by -\.c% (result will be -mod(i*j,3), which is negative.) - \_advance\.a by \.b% (result is negative of what's in the spec.) - \_edef\.maskfunctionresult{\_the\.a}% - }% - \_or - %Case 6: arrows - \_def\.parsemaskingfunction{% - % Compute mod( mod(\themaski*\themaskj,2) + mod(\themaski*\themaskj,3) , 2 ) % - \.a=\.maski% - \_multiply\.a by \.maskj% - \.b=\.a% - \.c=\.a% - \_multiply\.c by 2% % \.c equals 2*i*j. - \_divide\.a by 2% - \_multiply\.a by 2% - \_advance\.c by -\.a% Now \.c equals i*j + mod(i*j,2). - \_divide\.b by 3% - \_multiply\.b by 3% - \_advance\.c by -\.b% (Now \.c equals mod(i*j,2) + mod(i*j,3). - \.a=\.c% - \_divide\.a by 2% - \_multiply\.a by 2% - \_advance\.c by-\.a% - \_edef\.maskfunctionresult{\_the\.c}% - }% - \_or - %Case 7: shotgun - \_def\.parsemaskingfunction{% - % Compute mod( mod(\themaski+\themaskj,2) + mod(\themaski*\themaskj,3) , 2 ) % - \.a=\.maski% - \_advance\.a by \.maskj% %So \.a = i+j - \.b=\.maski% - \_multiply\.b by \.maskj% %So \.b = i*j - \.c=\.a% - \_advance\.c by \.b% So \.c = i+j+i*j - \_divide\.a by 2% - \_multiply\.a by 2% - \_advance\.c by -\.a% So \.c = mod(i+j,2) + i*j - \_divide\.b by 3% - \_multiply\.b by 3% - \_advance\.c by -\.b% So \.c = mod(i+j,2) + mod(i*j,3) - \.a=\.c% - \_divide\.c by 2% - \_multiply\.c by 2% - \_advance\.a by -\.c% - \_edef\.maskfunctionresult{\_the\.a}% - }% - \_fi -}% - -\_def\.checkifcellisinmask{% - % The current position is (\.iz,\.jz), in TeX counts, - % but the counters (maski,maskj) should contain - % the current position with indexing starting at 0. - % That is, maski = \.iz-1 and maskj = \.jz-1. - % - % \.parsemaskingfunction must have been set by a call to \.setmaskingfunction - \.parsemaskingfunction - \_ea\_ifnum\.maskfunctionresult=0\_relax - \.cellinmasktrue - \_else - \.cellinmaskfalse - \_fi -}% - -\_newcount\.maski -\_newcount\.maskj - -\_def\.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 - \.createduplicatematrix{#2}{#1}% - \.setmaskingfunction{#3}% - \.setcounter\.maski{-1}% - \.for \.iz = 1 to \.size by 1% - {\.stepcounter\.maski - \.setcounter\.maskj{-1}% - \.for \.jz = 1 to \.size by 1% - {\.stepcounter\.maskj - \.checkifcellisinmask - \_ifqr_cellinmask - \.checkifcurrentcellcontainsdata{#2}% - \_ifqr_currentcellcontainsdata - \.flipcurrentcell{#2}% - \_fi - \_fi - }% - }% -}% - -\_newifi\_ifqr_currentcellcontainsdata -\.currentcellcontainsdatafalse - -\_def\.iwhite{\.white}% -\_def\.iblack{\.black}% - -\_def\.checkifcurrentcellcontainsdata#1{% - % #1 = name of matrix - \.currentcellcontainsdatafalse - \_ea\_ifx\_csname #1@\_the\.iz @\_the\.jz\_endcsname\.iwhite - \.currentcellcontainsdatatrue - \_fi - \_ea\_ifx\_csname #1@\_the\.iz @\_the\.jz\_endcsname\.iblack - \.currentcellcontainsdatatrue - \_fi -}% - -\_def\.flippedblack{\.black}% -\_def\.flippedwhite{\.white}% - -\_def\.flipcurrentcell#1{% - % #1 = name of matrix - % (\.iz, \.jz) = current position, in TeX counts. - % This assumes the cell contains data, either black or white! - \_ea\_ifx\_csname #1@\_the\.iz @\_the\.jz\_endcsname\.iwhite - \.storetomatrix{#1}{\_the\.iz}{\_the\.jz}{\.flippedblack}% - \_else - \.storetomatrix{#1}{\_the\.iz}{\_the\.jz}{\.flippedwhite}% - \_fi -}% - -\_def\.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 \.mask_selected. - \.createduplicatematrix{originalmatrix}{#1}% - \.message{<Applying Mask 0...}% - \.applymask{originalmatrix}{#1}{0}% - \.message{done. Calculating penalty...}% - \.evaluatemaskpenalty{#1}% - \_xdef\.currentbestpenalty{\.penalty}% - \.message{penalty is \.penalty>^^J}% - \_gdef\.currentbestmask{0}% - \.for \.iz = 1 to 7 by 1% - {\.message{<Applying Mask \_the\.iz...}% - \.applymask{originalmatrix}{currentmasked}{\_the\.iz}% - \.message{done. Calculating penalty...}% - \.evaluatemaskpenalty{currentmasked}% - \.message{penalty is \.penalty>^^J}% - \_ea\_ea\_ea\_ifnum\_ea\.penalty\_ea<\.currentbestpenalty\_relax - %We found a better mask. - \_xdef\.currentbestmask{\_the\.iz}% - \.createduplicatematrix{#1}{currentmasked}% - \_xdef\.currentbestpenalty{\.penalty}% - \_fi - }% - \_xdef\.mask_selected{\.currentbestmask}% - \.message{<Selected Mask \.mask_selected>^^J}% -}% - -\_def\.Ni{3}% -\_def\.Nii{3}% -\_def\.Niii{40}% -\_def\.Niv{10}% -\_def\.fiveones{11111}% -\_def\.fivezeros{00000}% -\_def\.twoones{11}% -\_def\.twozeros{00}% -\_def\.finderA{00001011101}% -\_def\.finderB{10111010000}% -\_def\.finderBthree{1011101000}% -\_def\.finderBtwo{101110100}% -\_def\.finderBone{10111010}% -\_def\.finderBzero{1011101}% -\_newifi\_ifqr_stringoffive -\_def\.addpenaltyiii{% - \.addtocounter\.penaltyiii{\.Niii}% -}% -\_newcount\.totalones -\_newcount\.penaltyi -\_newcount\.penaltyii -\_newcount\.penaltyiii -\_newcount\.penaltyiv -\_def\.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\.black{1}\_def\.white{0}% - \_def\.blackfixed{1}\_def\.whitefixed{0}% - \_def\.formatsquare{0}% This is not stated in the specs, but seems - % to be the standard implementation. - \_def\.blank{0}% These would be any bits at the end. - % - \.setcounter\.totalones{0}% - \.for \.iz=1 to \.size by 1% - {\_def\.lastfive{z}% %The z is a dummy, that will be removed before any testing. - \.stringoffivefalse - \_def\.lasttwo_thisrow{z}% %The z is a dummy. - \_def\.lasttwo_nextrow{z}% %The z is a dummy. - \_def\.lastnine{z0000}% %The 0000 stands for the white space to the left. The z is a dummy. - \_def\.ignore_finderBat{0}% - \.for \.jz=1 to \.size by 1% - {\_edef\.newbit{\.matrixentry{#1}{\_the\.iz}{\_the\.jz}}% - % - % LASTFIVE CODE FOR PENALTY 1 - % First, add the new bit to the end. - \_ea\.xaddto\_ea\.lastfive\_ea{\.newbit}% - \_ifnum\.jz<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. - \.removefirsttoken\.lastfive% - \_ifx\.lastfive\.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{\.Ni}% - \_global\.stringoffivetrue - \_fi - \_else - \_ifx\.lastfive\.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{\.Ni}% - \_global\.stringoffivetrue - \_fi - \_else - %This is not a string of five 1's or five 0's. - \_global\.stringoffivefalse - \_fi - \_fi - \_fi - % - % 2x2 BLOCKS FOR PENALTY 2 - % Every 2x2 block of all 1's counts for \.Nii penalty points. - % We do not need to run this test in the last row. - \_ea\_ifnum\_ea\.iz\_ea<\.size\_relax - \_ea\.xaddto\_ea\.lasttwo_thisrow\_ea{\.newbit}% - %Compute \.iplusone - \.a=\.iz\_relax% - \_advance\.a by 1% - \_edef\.iplusone{\_the\.a}% - % - \_edef\.nextrowbit{\.matrixentry{#1}{\.iplusone}{\_the\.jz}}% - \_ea\.xaddto\_ea\.lasttwo_nextrow\_ea{\.nextrowbit}% - \_ifnum\.jz<2\_relax% - %Still in the first column; no check. - \_else - %Second column or later. Remove the old bits, and then test. - \.removefirsttoken\.lasttwo_thisrow - \.removefirsttoken\.lasttwo_nextrow - \_ifx\.lasttwo_thisrow\.twoones - \_ifx\.lasttwo_nextrow\.twoones - \.addtocounter\.penaltyii{\.Nii}% - \_fi - \_else - \_ifx\.lasttwo_thisrow\.twozeros - \_ifx\.lasttwo_nextrow\.twozeros - \.addtocounter\.penaltyii{\.Nii}% - \_fi - \_fi - \_fi - \_fi - \_fi - % - % LASTNINE CODE FOR PENALTY 3 - % First, add the new bit to the end. - \_ea\.xaddto\_ea\.lastnine\_ea{\.newbit}% - \_ifnum\.jz<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. - \.removefirsttoken\.lastnine - \_ea\_ifnum\.size=\.jz\_relax% - % Last column. Any of the following should count: - % 1011101 (\.finderBzero) - % 10111010 (\.finderBone) - % 101110100 (\.finderBtwo) - % 1011101000 (\.finderBthree) - % 10111010000 (\.finderB) - \_ifx\.lastnine\.finderB - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBthree - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBtwo - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBone - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBzero - \.addpenaltyiii - \_fi - \_fi - \_fi - \_fi - \_fi - \_else - \_ifx\.lastnine\.finderA% %Matches 0000 1011101 - \.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 \.ignore_finderBat to \.jz+4. - \.a=\.jz\_relax% - \_advance\.a by 4% - \_xdef\.ignore_finderBat{\_the\.a}% - \_else - \_ifx\.lastfive\.finderB% %Matches 1011101 0000. - \_ea\_ifnum\.ignore_finderBat=\.jz\_relax - %This pattern was *not* counted already earlier. - \.addpenaltyiii - \_fi - \_fi - \_fi - \_fi - \_fi - % - %COUNT 1's FOR PENALTY 4 - \_ea\_ifnum\.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. - \.for \.jz=1 to \.size by 1% - {\_def\.lastfive{z}% %The z is a dummy, that will be removed before any testing. - \.stringoffivefalse - \_def\.lastnine{z0000}% %The 0000 stands for the white space to the left. The z is a dummy. - \_def\.ignore_finderBat{0}% - \.for \.iz=1 to \.size by 1% - {\_edef\.newbit{\.matrixentry{#1}{\_the\.iz}{\_the\.jz}}% - % - % LASTFIVE CODE FOR PENALTY 1 - % First, add the new bit to the end. - \_ea\.xaddto\_ea\.lastfive\_ea{\.newbit}% - \_ifnum\.iz<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. - \.removefirsttoken\.lastfive - \_ifx\.lastfive\.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{\.Ni}% - \_global\.stringoffivetrue - \_fi - \_else - \_ifx\.lastfive\.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{\.Ni}% - \_global\.stringoffivetrue - \_fi - \_else - %This is not a string of five 1's or five 0's. - \_global\.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. - \_ea\.xaddto\_ea\.lastnine\_ea{\.newbit}% - \_ifnum\.iz<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. - \.removefirsttoken\.lastnine - \_ea\_ifnum\.size=\.iz\_relax% - % Last column. Any of the following should count: - % 1011101 (\.finderBzero) - % 10111010 (\.finderBone) - % 101110100 (\.finderBtwo) - % 1011101000 (\.finderBthree) - % 10111010000 (\.finderB) - \_ifx\.lastnine\.finderB - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBthree - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBtwo - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBone - \.addpenaltyiii - \_else - \.removefirsttoken\.lastnine - \_ifx\.lastnine\.finderBzero - \.addpenaltyiii - \_fi - \_fi - \_fi - \_fi - \_fi - \_else - \_ifx\.lastnine\.finderA% %Matches 0000 1011101 - \.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 \.ignore_finderBat to \.iz+4. - \.a=\.iz\_relax% - \_advance\.a by 4% - \_xdef\.ignore_finderBat{\_the\.a}% - \_else - \_ifx\.lastfive\.finderB% %Matches 1011101 0000. - \_ea\_ifnum\.ignore_finderBat=\.iz\_relax - %This pattern was *not* counted already earlier. - \.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. - % - \.a=\.totalones\_relax - \_multiply\.a by 20\_relax - \.b=\.size\_relax - \_multiply\.b by \.size\_relax - \.c=10\_relax - \_multiply\.c by \.b\_relax - \_advance\.a by -\.c\_relax - \_ifnum\.a<0\_relax - \_multiply\.a by -1\_relax - \_fi - \_divide\.a by \.b\_relax - \.setcounter\.penaltyiv{\_the\.a}% - % - %CALCULATE TOTAL PENALTY - \.a=\_the\.penaltyi\_relax% - \_advance\.a by \_the\.penaltyii\_relax% - \_advance\.a by \_the\.penaltyiii\_relax% - \_advance\.a by \_the\.penaltyiv\_relax% - \_edef\.penalty{\_the\.a}% -}% - -\_def\.removefirsttoken#1{% - %Removes the first token from the macro named in #1. - \_edef\.argument{(#1)}% - \_ea\.removefirsttoken_int\.argument% - \_xdef#1{\.removefirsttoken_result}% -}% -\_def\.removefirsttoken_int(#1#2){% - \_def\.removefirsttoken_result{#2}% -}% - -\_def\.writeformatstring#1#2{% - % #1 = matrix name - % #2 = binary string representing the encoded and masked format information - \.setcounter\.i{9}% - \.setcounter\.j{1}% - \_edef\.argument{{#1}(#2\_relax)}% - \_ea\.writeformatA_recursive\.argument - % - \.setcounter\.i{\.numberofrowsinmatrix{#1}}% - \.setcounter\.j{9}% - \_ea\.writeformatB_recursive\.argument -}% - -\_def\.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 counters) - \_ifnum#2=1\_relax - \.storetomatrix{#1}{\_the\.i}{\_the\.j}{\.blackformat}% - \_else - \.storetomatrix{#1}{\_the\.i}{\_the\.j}{\.whiteformat}% - \_fi - % Now the tricky part--moving \.iz and \.jz to their next positions. - \_ifnum\.j<9\_relax - %If we're not yet in column 9, move right. - \.stepcounter\.j - \_ifnum\.j=7\_relax - %But we skip column 7! - \.stepcounter\.j - \_fi - \_else - %If we're in column 9, we move up. - \.addtocounter\.i{-1}% - \_ifnum\.i=7\_relax - %But we skip row 7! - \.addtocounter\.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\.i<1 - \_let\.nexttoken=\_relax - \_else - \_def\.nexttoken{\.writeformatA_recursive{#1}(#3)}% - \_fi - \.nexttoken -}% - -\_def\.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 counters) - \_ifnum#2=1\_relax - \.storetomatrix{#1}{\_the\.i}{\_the\.j}{\.blackformat}% - \_else - \.storetomatrix{#1}{\_the\.i}{\_the\.j}{\.whiteformat}% - \_fi - % Now the tricky part--moving counters i and j to their next positions. - \.a=\.size% - \_advance\.a by -6\_relax% - \_ifnum\.a<\.i\_relax - %If we're not yet in row n-6, move up. - \.addtocounter\.i{-1}% - \_else - \_ifnum\.a=\.i\_relax - %If we're actually in row n-6, we jump to position (9,n-7). - \.setcounter\.i{9}% - %Set counter j equal to \.size-7. - \_global\.j=\.size\_relax% - \_global\_advance\.j by -7\_relax% - \_else - %Otherwise, we must be in row 9. - %In this case, we move right. - \.stepcounter\.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. - \_ea\_ifnum\.size<\.j\_relax - \_let\.nexttoken=\_relax - \_else - \_def\.nexttoken{\.writeformatB_recursive{#1}(#3)}% - \_fi - \.nexttoken -}% - -\_def\.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. - \_ea\_ifnum\.version>6\_relax - %Move to position (n-8,6). - \.setcounter\.i{\.size}\_relax% - \.addtocounter\.i{-8}\_relax% - \.setcounter\.j{6}% - \_edef\.argument{{#1}(#2\_relax)}% - \_ea\.writeversion_recursive\.argument - \_fi -}% - -\_def\.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 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 \.topline equal to n-10. - \.a=\.size\_relax% - \_advance\.a by -10\_relax% - \_edef\.topline{\_the\.a}% - % - \_ifnum#2=1\_relax - \.storetomatrix{#1}{\_the\.i}{\_the\.j}{\.blackformat}% - \.storetomatrix{#1}{\_the\.j}{\_the\.i}{\.blackformat}% - \_else - \.storetomatrix{#1}{\_the\.i}{\_the\.j}{\.whiteformat}% - \.storetomatrix{#1}{\_the\.j}{\_the\.i}{\.whiteformat}% - \_fi - % Now the tricky part--moving counters i and j to their next positions. - \.addtocounter\.i{-1}% - \_ea\_ifnum\.topline>\.i\_relax - %We've overshot the top of the region. - %We need to move left one column and down three. - \.addtocounter\.j{-1}% - \.addtocounter\.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\.j<1\_relax - \_let\.nexttoken=\_relax - \_else - \_def\.nexttoken{\.writeversion_recursive{#1}(#3)}% - \_fi - \.nexttoken -}% -\_newcount\.hexchars - -\_def\.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. - % - %Now comes the actual data. - % - {\_endlinechar=-1 \_xdef\.codetext{4\.utfstring{#1}0}}% - %The terminator is 0 - %\.xaddto\.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\.hexchars{0}% - \.getstringlength{\.codetext}% - \.setcounter\.hexchars{\.stringlength}% - %Set \.numpaddingcodewords equal to \.totaldatacodewords - hexchars/2. - \.a=-\.hexchars\_relax - \_divide\.a by 2\_relax - \_advance\.a by \.totaldatacodewords\_relax - \_edef\.numpaddingcodewords{\_the\.a}% - % - \_ea\_ifnum\.numpaddingcodewords<0% - \_edef\.ds{ERROR: Too much data! Over by \.numpaddingcodewords bytes.}\_show\.ds - \_fi - \_ea\_ifnum\.numpaddingcodewords>0% - \.for \.iz = 2 to \.numpaddingcodewords by 2% - {\.xaddto{\.codetext}{ec11}}% - \_ea\_ifodd\.numpaddingcodewords\_relax - \.xaddto{\.codetext}{ec}% - \_fi - \_fi -}% - -\_def\.splitcodetextintoblocks{% - \.setcounter\.i{0}% - \.for \.jz = 1 to \.numshortblocks by 1% - {\.stepcounter\.i - \.splitoffblock{\.codetext}{\_the\.i}{\.shortblock_size}% - }% - \_ea\_ifnum\.numlongblocks>0\_relax - \.for \.jz = 1 to \.numlongblocks by 1% - {\.stepcounter\.i - \.splitoffblock{\.codetext}{\_the\.i}{\.longblock_size}% - }% - \_fi -}% - -\_def\.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{<Splitting off block #2>}% - \_ea\_gdef\_csname datablock@#2\_endcsname{}% %This line is important! - \.for \.iz = 1 to #3 by 1% - {\_edef\.argument{{#2}(#1)}% - \_ea\.splitoffblock_int\.argument - }% -}% - -\_def\.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. - \_ea\_xdef\_csname datablock@#1\_endcsname{\_csname datablock@#1\_endcsname#2#3}% - \_xdef\.codetext{#4}% -}% - -\_def\.createerrorblocks{% - \.for \.ii = 1 to \.numblocks by 1% - {\.message{<Making error block \_the\.ii>}% - \.FXgenerate_errorbytes{\_csname datablock@\_the\.ii\_endcsname}{\.numeccodewords}% - \_ea\_xdef\_csname errorblock@\_the\.ii\_endcsname{\.FXerrorbytes}% - }% -}% - -\_def\.interleave{% - \.setcounter\.i{0}% - \_def\.interleaved_text{}% - \.message{<Interleaving datablocks of length \.shortblock_size\_space and \.longblock_size: }% - \.for \.ii = 1 to \.shortblock_size by 1% - {\.for \.jj = 1 to \.numblocks by 1% - {\.writefromblock{datablock}{\_the\.jj}% - }% - \.message{\_the\.ii,}% - }% - %The long blocks are numbered \.numshortblocks+1, \.numshortblocks+2, ..., \.numblocks. - \.a=\.numshortblocks\_relax - \_advance\.a by 1\_relax - \.for \.jj = \.a to \.numblocks by 1% - {\.writefromblock{datablock}{\_the\.jj}}% - \_ea\_ifnum\.numlongblocks>0\_relax% - \.message{\.longblock_size.>}% - \_else - \.message{.>}% - \_fi - \.message{<Interleaving errorblocks of length \.numeccodewords: }% - \.for \.ii = 1 to \.numeccodewords by 1% - {\.message{\_the\.ii,}% - \.for \.jj = 1 to \.numblocks by 1% - {\.writefromblock{errorblock}{\_the\.jj}% - }% - }% - \.message{.><Interleaving complete.>}% -}% - -\_def\.writefromblock#1#2{% - % #1 = either 'datablock' or 'errorblock' - % #2 = block number, in {1,...,\.numblocks}% - \_edef\.argument{(\_csname #1@#2\_endcsname\_relax\_relax\_relax)}% - \_ea\.writefromblock_int\.argument - \_ea\_xdef\_csname #1@#2\_endcsname{\.writefromblock_remainder}% -}% - -\_def\.writefromblock_int(#1#2#3){% - % #1#2 = first byte (in hex) of text, which will be written to \.interleaved_text - % #3 = remainder, including \_relax\_relax\_relax terminator. - \.xaddto{\.interleaved_text}{#1#2}% - \.writefromblock_intint(#3)% -}% - -\_def\.writefromblock_intint(#1\_relax\_relax\_relax){% - \_xdef\.writefromblock_remainder{#1}% -}% - -\_newifi\_ifqr_leadingcoeff -\_def\.testleadingcoeff(#1#2){% - % Tests whether the leading digit of #1#2 is 1. - \_ifnum#1=1\_relax - \.leadingcoefftrue - \_else - \.leadingcoefffalse - \_fi -}% - -\_def\.polynomialdivide#1#2{% - \_edef\.numerator{#1}% - \_edef\.denominator{#2}% - \.divisiondonefalse% - \_ea\_ea\_ea\.oneroundofdivision\_ea\_ea\_ea{\_ea\.numerator\_ea}\_ea{\.denominator}% -}% - -\_def\.empty{}% -\_def\.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. - % - \.testleadingcoeff(#1)% - \_ifqr_leadingcoeff - \.xorbitstrings{#1}{#2}% - \_ifqr_xorfailed - %If xor failed, that means our #1 was already the remainder! - \.divisiondonetrue - \_edef\.theremainder{#1}% - \_else - %xor succeeded. We need to recurse. - \_ea\_ea\_ea\_edef\_ea\_ea\_ea\.numerator\_ea\_ea\_ea{\_ea\.stripleadingzero\_ea(\.xorresult)}% - \_fi - \_else - \_ea\_def\_ea\.numerator\_ea{\.stripleadingzero(#1)}% - \_ifx\.numerator\.empty - \.divisiondonetrue - \_def\.theremainder{0}% - \_fi - \_fi - \_ifqr_divisiondone - \_relax - \_else - \_ea\.oneroundofdivision\_ea{\.numerator}{#2}% - \_fi -}% - -\_def\.stripleadingzero(0#1){#1}%Strips off a leading zero. - -\_newifi\_ifqr_xorfailed% This flag will trigger when #2 is longer than #1. - -\_def\.xorbitstrings#1#2{% - % #1 = bitstring - % #2 = bitstring no longer than #1 - \.xorfailedfalse - \_edef\.argument{(,#1\_relax\_relax)(#2\_relax\_relax)}% - \_ea\.xorbitstrings_recursive\.argument - %\.xorbitstrings_recursive(,#1\_relax\_relax)(#2\_relax\_relax)% -}% - -\_def\.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\.testii{#2}% - \_def\.testiv{#4}% - \_ifx\.testii\.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\.testiv\.relax - %No problem. We are done. - \.xorbit_saveresult(#1#2#3)% - \_else - %Problem! The second string was longer than the first. - \.xorfailedtrue - \_def\.xorresult{}% - \_fi - \_else - % There is still a bit to manipulate in #2. - % Check whether #4 contains anything. - \_ifx\.testiv\.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. - \.xorbit_saveresult(#1#2#3)% - \_else - % Yes, #4 still has something to XOR. Do the task. - \_ifnum#2=#4\_relax - \.xorbitstrings_recursive(#1% - 0,#3)(#5)% - \_else - \.xorbitstrings_recursive(#1% - 1,#3)(#5)% - \_fi - \_fi - \_fi -}% - -\_def\.xorbit_saveresult(#1\_relax\_relax){% - %Strips off the extra '\_relax'es at the end. - \_def\.xorresult{#1}% -}% - -\_newifi\_ifqr_divisiondone - -\_def\.BCHcode#1{% - \_edef\.formatinfo{#1}% - \_def\.formatinfopadded{\.formatinfo 0000000000}% - \_def\.divisor{10100110111}% - \.divisiondonefalse - \.polynomialdivide{\.formatinfopadded}{\.divisor}% - % - \.getstringlength{\.theremainder}% - %Run loop from stringlength+1 to 10. - \.a=\.stringlength\_relax% - \_advance\.a by 1\_relax% - \.for \.iz = \.a to 10 by 1% - {% - \_xdef\.theremainder{0\.theremainder}% - }% - \_edef\.BCHresult{\.formatinfo\.theremainder}% -}% - -\_def\.formatmask{101010000010010}% - -\_def\.encodeandmaskformat#1{% - \.BCHcode{#1}% - \.xorbitstrings{\.BCHresult}{\.formatmask}% - \_edef\.formatbitstring{\.xorresult}% -}% - -\_def\.Golaycode#1{% - % #1 = 6-bit version number - \_edef\.versioninfo{#1}% - \_def\.versioninfopadded{\.versioninfo 000000000000}% %Append 12 zeros. - \_def\.divisor{1111100100101}% - \.divisiondonefalse - \.polynomialdivide{\.versioninfopadded}{\.divisor}% - % - \.getstringlength{\.theremainder}% - %Run loop from stringlength+1 to 12. - \.a=\.stringlength\_relax% - \_advance\.a by 1\_relax% - \.for \.iz = \.a to 12 by 1% - {% - \_xdef\.theremainder{0\.theremainder}% - }% - \_edef\.Golayresult{\.versioninfo\.theremainder}% -}% -\_def\.Fresult{}% - -\_def\.xorbitstring#1#2#3{% - % #1 = new macro to receive result - % #2, #3 = bitstrings to xor. The second can be shorter than the first. - \_def\.xor_result{}% - \_edef\.argument{(#2\_relax\_relax)(#3\_relax\_relax)}% - \_ea\.xorbitstring_recursive\.argument% - \_edef#1{\.xor_result}% -}% -\_def\.xorbitstring_recursive(#1#2)(#3#4){% - \_edef\.testi{#1}% - \_ifx\.testi\.relax% - %Done. - \let\.next=\_relax% - \_else - \_if#1#3\_relax - \.xaddto{\.xor_result}{0}% - \_else - \.xaddto{\.xor_result}{1}% - \_fi - \_edef\.next{\_noexpand\.xorbitstring_recursive(#2)(#4)}% - \_fi - \.next -} - -\_def\.Faddchar_raw#1#2{% - %Add two hexadecimal digits using bitwise xor - \.hextobinary[4]{\.summandA}{#1}% - \.hextobinary[4]{\.summandB}{#2}% - \.xorbitstring{\.Fresult}{\.summandA}{\.summandB}% - \.binarytohex[1]{\.Fresult}{\.Fresult}% -}% - -\_def\.canceltwos#1{% - \_edef\.argument{(#1\_relax\_relax)}% - \_ea\.canceltwos_int\.argument% -}% - -\_def\.canceltwos_int(#1#2){% - \_ea\.canceltwos_recursion(,#1#2)% -}% - -\_def\.canceltwos_recursion(#1,#2#3){% - \_def\.testii{#2}% - \_ifx\.testii\.relax - %Cancelling complete. - \.striptworelaxes(#1#2#3)% - %Now \.Fresult contains the answer. - \_else - \_relax - \_ifnum#2=2\_relax - \.canceltwos_recursion(#10,#3)% - \_else - \.canceltwos_recursion(#1#2,#3)% - \_fi - \_fi -}% - -\_def\.striptworelaxes(#1\_relax\_relax){% - \_gdef\.Fresult{#1}% -}% - -\.for \.iz = 0 to 15 by 1% - {\.decimaltohex[1]{\.tempa}{\_the\.iz}% - \.for \.jz = 0 to 15 by 1% - {\.decimaltohex[1]{\.tempb}{\_the\.jz}% - \.Faddchar_raw\.tempa\.tempb - \_ea\_xdef\_csname F@addchar@\.tempa\.tempb\_endcsname{\.Fresult}% - }% - }% - -\_def\.Faddchar#1#2{% - \_ea\_def\_ea\.Fresult\_ea{\_csname F@addchar@#1#2\_endcsname}% -}% - -\_def\.Faddstrings#1#2{% - \_edef\.argument{(,#1\_relax\_relax)(#2\_relax\_relax)}% - \_ea\.Faddstrings_recursion\.argument% -}% - -\_def\.Faddstrings_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\.testii{#2}% - \_def\.testiv{#4}% - \_ifx\.testii\.relax - %The entire string has been processed. - \_gdef\.Fresult{#1}% - \_else - \_ifx\.testiv\.relax - %The second string is over. - \.striptworelaxes(#1#2#3)% - %Now \.Fresult contains the answer. - \_else - %We continue to add. - \.Faddchar{#2}{#4}% - \_edef\.argument{(#1\.Fresult,#3)(#5)}% - \_ea\.Faddstrings_recursion\.argument% - \_fi - \_fi -}% -\_gdef\.Fstripleadingzero(0#1){\_edef\.Fresult{#1}}% - -\.i=0% -\_def\.poweroftwo{1}% -\.for \.iz = 1 to 254 by 1% - {\_global\_advance\.i by1% - \.a=\.poweroftwo\_relax - \_multiply\.a by 2\_relax - \_edef\.poweroftwo{\_the\.a}% - \.decimaltohex[2]{\.poweroftwo_hex}{\.poweroftwo}% - \_ea\_ifnum\.poweroftwo>255\_relax - %We need to bitwise add the polynomial represented by 100011101, i.e. 0x11d. - \.Faddstrings{\.poweroftwo_hex}{11d}% %Now it should start with 0. - \_ea\.Fstripleadingzero\_ea(\.Fresult)% %Now it should be two hex digits. - \_edef\.poweroftwo_hex{\.Fresult}% %Save the hex version. - \.hextodecimal{\.poweroftwo}{\.Fresult}% - \_fi - \_xdef\.poweroftwo{\.poweroftwo}% - \_ea\_xdef\_csname F@twotothe@\_the\.i\_endcsname{\.poweroftwo_hex}% - \_ea\_xdef\_csname F@logtwo@\.poweroftwo_hex\_endcsname{\_the\.i}% - }% -\_ea\_xdef\_csname F@twotothe@0\_endcsname{01}% -\_ea\_xdef\_csname F@logtwo@01\_endcsname{0}% - -\_def\.Ftwotothe#1{% - \_ea\_xdef\_ea\.Fresult\_ea{\_csname F@twotothe@#1\_endcsname}% -}% -\_def\.Flogtwo#1{% - \_ea\_xdef\_ea\.Fresult\_ea{\_csname F@logtwo@#1\_endcsname}% -}% - -\_def\.zerozero{00}% - -\_def\.Fmultiply#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 \.Fresult - \_edef\.argA{#1}% - \_edef\.argB{#2}% - \_ifx\.argA\.zerozero - \_def\.Fresult{00}% - \_else - \_ifx\.argB\.zerozero - \_def\.Fresult{00}% - \_else - \_ea\.Flogtwo\_ea{\.argA}% - \_edef\.logA{\.Fresult}% - \_ea\.Flogtwo\_ea{\.argB}% - \_edef\.logB{\.Fresult}% - \_ea\.a\_ea=\.logA\_relax% \.a = \logA - \_ea\_advance\_ea\.a\.logB\_relax% \advance \.a by \logB - \_ifnum\.a>254\_relax% - \_advance\.a by -255\_relax - \_fi - \_ea\.Ftwotothe\_ea{\_the\.a}% - % Now \.Fresult contains the product, as desired. - \_fi - \_fi -}% - -\_newifi\_ifqr_FXleadingcoeff_zero -\_def\.FXtestleadingcoeff(#1#2#3){% - % Tests whether the leading coefficient of the hex-string #1#2#3 is '00'. - \_edef\.FXleadingcoefficient{#1#2}% - \.FXleadingcoeff_zerofalse - \_ifx\.FXleadingcoefficient\.zerozero - \.FXleadingcoeff_zerotrue - \_fi -}% - -\_newifi\_ifqr_FXdivisiondone - -\_newcount\.divisionsremaining %Keep track of how many divisions to go! -\_def\.FXpolynomialdivide#1#2{% - \_edef\.FXnumerator{#1}% - \_edef\.denomin{#2}% - \.getstringlength\.FXnumerator - \.setcounter\.divisionsremaining{\.stringlength}% - \.getstringlength\.denomin - \.addtocounter\.divisionsremaining{-\.stringlength}% - \.addtocounter\.divisionsremaining{2}% - \_divide\.divisionsremaining by 2\_relax %2 hex chars per number - \.FXdivisiondonefalse - \_ea\_ea\_ea\.FXpolynomialdivide_recursive\_ea\_ea\_ea{\_ea\.FXnumerator\_ea}\_ea{\.denomin}% -}% - -\_def\.FXpolynomialdivide_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. - % - \.FXtestleadingcoeff(#1)% - \_ifqr_FXleadingcoeff_zero - %Leading coefficient is zero, so remove it. - \_ea\_def\_ea\.FXnumerator\_ea{\.FXstripleadingzero(#1)}% - \_else% - %Leading coefficient is nonzero, and contained in \.FXleadingcoefficient - \.FXsubtractphase{#1}{#2}{\.FXleadingcoefficient}% - \_ifqr_FXsubtractfailed - %If subtraction failed, that means our #1 was already the remainder! - \.FXdivisiondonetrue - \_edef\.theremainder{#1}% - \_else% - %xor succeeded. We need to recurse. - \_ea\_ea\_ea\_edef\_ea\_ea\_ea\.FXnumerator\_ea\_ea\_ea{\_ea\.FXstripleadingzero\_ea(\.FXsubtraction_result)}% - \_fi% - \_fi% - \.addtocounter\.divisionsremaining{-1}% - \_ifnum\.divisionsremaining=0\_relax - %Division is done! - \.FXdivisiondonetrue - \_edef\.theremainder{\.FXnumerator}% - \_relax% - \_else% - \_ea\.FXpolynomialdivide_recursive\_ea{\.FXnumerator}{#2}% - \_fi% -}% - -\_def\.FXstripleadingzero(00#1){#1}%Strips off a single leading zero of F_256. - -\_newifi\_ifqr_FXsubtractfailed% This flag will trigger when #2 is longer than #1. - -\_def\.FXsubtractphase#1#2#3{% - % #1 = bitstring - % #2 = bitstring no longer than #1 - % #3 = leading coefficient - \.FXsubtractfailedfalse - \_edef\.argument{(,#1\_relax\_relax\_relax)(#2\_relax\_relax\_relax)(#3)}% - \_ea\.FXsubtract_recursive\.argument% -}% - -\_def\.FXsubtract_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\.testii{#2}% - \_def\.testv{#5}% - \_ifx\.testii\.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\.testv\.relax - %No problem. We are done. - \.FXsubtract_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. - \.FXsubtractfailedtrue - \_def\.FXsubtraction_result{}% - \_fi - \_else - % There is still a coefficient to manipulate in #2#3. - % Check whether #5 contains anything. - \_ifx\.testv\.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. - \.FXsubtract_saveresult(#1#2#3#4)% - \_else - % Yes, #5#6 still has something to XOR. Do the task. - \.Fmultiply{#5#6}{#8}% Multiply by the factor 'a'. - \.Faddstrings{#2#3}{\.Fresult}% Subtract. (We're in characteristic two, so adding works.) - \_edef\.argument{(#1\.Fresult,#4)(#7)(#8)}% - \_ea\.FXsubtract_recursive\.argument% - \_fi - \_fi -}% - -\_def\.FXsubtract_saveresult(#1\_relax\_relax\_relax){% - %Strips off the three extra '\_relax'es at the end. - \_def\.FXsubtraction_result{#1}% -}% - -\_def\.FXcreategeneratorpolynomial#1{% - % #1 = n, the number of error codewords desired. - % We need to create \prod_{j=0}^{n-1} (x-2^j). - \_edef\.FXgenerator_degree{#1}% - \_def\.FXgeneratorpolynomial{01}% Initially, set it equal to 1. - \.setcounter\.i{0}% - \.FXcreategenerator_recursive% - %The result is now stored in \.FXgeneratorpolynomial -}% - -\_def\.FXcreategenerator_recursive{% - % \.FXgeneratorpolynomial 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 \.FXgeneratorpolynomial 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\.summandA{\.FXgeneratorpolynomial 00}% This is f(x) * x - \_edef\.summandB{00\.FXgeneratorpolynomial}% This is f(x), with a 0x^{i+1} in front. - \.Ftwotothe{\_the\.i}% - \_edef\.theconstant{\.Fresult}% - \.FXsubtractphase{\.summandA}{\.summandB}{\.theconstant}% - %This calculates \.summandA + \.theconstant * \.summandB - %and stores the result in \.FXsubtraction_result - \_edef\.FXgeneratorpolynomial{\.FXsubtraction_result}% - \.stepcounter\.i - \_ea \_ifnum\.FXgenerator_degree=\.i\_relax - %We just multiplied by (x-2^{n-1}), so we're done. - \_relax - \_else% - %We need to do this again! - \_ea \.FXcreategenerator_recursive - \_fi -}% - -\_def\.FXgenerate_errorbytes#1#2{% - % #1 = datastream in hex - % #2 = number of error correction bytes requested - \_edef\.numerrorbytes{#2}% - \_ea\.FXcreategeneratorpolynomial\_ea{\.numerrorbytes}% - \_edef\.FXnumerator{#1}% - \.for \.iz = 1 to \.numerrorbytes by 1% - {\.xaddto\.FXnumerator{00}}% %One error byte means two hex codes. - \.FXpolynomialdivide{\.FXnumerator}{\.FXgeneratorpolynomial}% - \_edef\.FXerrorbytes{\.theremainder}% -}% -\_newifi\_ifqr_versionmodules - -\_def\.level_char#1{% - \_ea\_ifcase#1 - M\_or L\_or H\_or Q\_fi}% - -\_newifi\_ifqr_versiongoodenough -\_def\.choose_bestversion#1{% - % \.desiredversion = user-requested version - % \.desiredlevel = user-requested error-correction level - \_edef\.stringlength{\.utfstringlen{#1}}% - % - %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\.versiongoodenoughfalse% - \_gdef\.bestversion{0}% - \_gdef\.bestlevel{0}% - \_ifnum\.desiredversion=0\_relax - \.a=1\_relax - \_else - \.a=\.desiredversion\_relax - \_fi - \.for \.iz=\.a to 40 by 1 - {\_edef\.version{\_the\.iz}% - \_global\.versiongoodenoughfalse - \.for \.jz=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. - \.a = \.jz\_relax - \_divide \.a by 2\_relax - \_multiply \.a by 4\_relax - \_advance \.a by 1\_relax - \_advance \.a by -\.jz\_relax - \_edef\.level{\_the\.a}% - \_ifnum\.desiredlevel=\.a\_relax - \_global\.versiongoodenoughtrue - \_fi - \_ifqr_versiongoodenough - \.calculate_capacity{\.version}{\.level}% - \_ea\_ea\_ea\_ifnum\_ea\.truecapacity\_ea<\.stringlength\_relax - %Too short - \_relax - \_else - %Long enough! - \_xdef\.bestversion{\.version}% - \_xdef\.bestlevel{\.level}% - \_global\.iz=40% - \_fi - \_fi - }% - }% - \_edef\.version{\.bestversion}% - \_edef\.level{\.bestlevel}% - \_ea\_ifnum\.desiredversion>0\_relax - \_ifx\.bestversion\.desiredversion\_relax - %No change from desired version. - \_else - %Version was increased - \.message{<Requested QR version '\.desiredversion' is too small for desired text.}% - \.message{Version increased to '\.bestversion' to fit text.>^^J}% - \_fi - \_fi - \_ifx\.bestlevel\.desiredlevel\_relax - %No change in level. - \_else - \.message{<Error-correction level increased from \.level_char{\.desiredlevel}}% - \.message{to \.level_char{\.bestlevel} at no cost.>^^J}% - \_fi -}% - -\_def\.calculate_capacity#1#2{% - \_edef\.version{#1}% - \_edef\.level{#2}% - %Calculate \.size, the number of modules per side. - % The formula is 4\.version+17. - \.a=\.version\_relax - \_multiply\.a by 4\_relax - \_advance\.a by 17\_relax - \_xdef\.size{\_the\.a}% - % - % Calculate \.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( \.version / 7 ), except that k=0 for version 1. - \_ea\_ifnum\.version=1\_relax% - \_def\.k{0}% - \_else% - \.a=\.version\_relax - \_divide \.a by 7\_relax - \_advance\.a by 2\_relax - \_edef\.k{\_the\.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. - \.a=\.size\_relax - \_multiply\.a by 2\_relax - \_advance\.a by 160\_relax - \_ea\_ifnum\.k=0\_relax\_else - %\.k is nonzero, hence at least 2, so we continue to add 25(k^2-3)-10(k-2). - \.b=\.k\_relax - \_multiply\.b by \.k\_relax - \_advance\.b by -3\_relax - \_multiply\.b by 25\_relax - \_advance\.a by \.b\_relax - \.b=\.k\_relax - \_advance\.b by -2\_relax - \_multiply\.b by 10\_relax - \_advance\.a by -\.b\_relax - \_fi - \_edef\.numfunctionpatternmodules{\_the\.a}% - % - %Calculate the number of version modules, either 36 or 0. - \_ea\_ifnum\.version>6\_relax - \.versionmodulestrue - \_def\.numversionmodules{36}% - \_else - \.versionmodulesfalse - \_def\.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 \.numdatacodewords; - %the leftover bits are \.numremainderbits. - \.a=\.size\_relax - \_multiply \.a by \.size\_relax - \_advance \.a by -\.numfunctionpatternmodules\_relax - \_advance \.a by -31\_relax% % There are 31 format modules. - \_advance \.a by -\.numversionmodules\_relax - \.b=\.a\_relax - \_divide \.a by 8\_relax - \_edef\.numdatacodewords{\_the\.a}% - \_multiply\.a by 8\_relax - \_advance \.b by -\.a\_relax - \_edef\.numremainderbits{\_the\.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. - \_ea\_ifnum\.version<10\_relax - \_def\.charactercountbytes_byte{1}% - \_def\.charactercountbits_byte{8}% - \_else - \_def\.charactercountbytes_byte{2}% - \_def\.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 \.totaldatacodewords. - % The following macro sets \.numblocks and \.numeccodewords - % based on Table 9 of the QR specification. - \.settableix - \.a = -\.numblocks\_relax - \_multiply \.a by \.numeccodewords\_relax - \_advance\.a by \.numdatacodewords\_relax - \_edef\.totaldatacodewords{\_the\.a}% - \_advance\.a by -\.charactercountbytes_byte\_relax%Subtract character count - \_advance\.a by -1\_relax% Subtract 1 byte for the 4-bit mode indicator and the 4-bit terminator at the end. - \_edef\.truecapacity{\_the\.a}% -} - -\_def\.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 \setversion should be called every time! - % - \_edef\.version{#1}% - \_edef\.level{#2}% - % - \.calculate_capacity{\.version}{\.level}% - %The capacity-check code sets the following: - % * \.size - % * \.k - % * \_ifqr_versionmodules - % * \.numversionmodules - % * \.numdatacodewords - % * \.numremainderbits - % * \.charactercountbits_byte - % * \.charactercountbytes_byte - % * \.numblocks (via \.settableix) - % * \.numeccodewords (via \.settableix) - % * \.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. - % - \.a = \.size\_relax - \_advance\.a by -13\_relax - \_multiply\.a by 2\_relax - \.b = \.k\_relax - \_advance \.b by -1\_relax - \_divide\.a by \.b\_relax - \_advance\.a by 3\_relax - \_divide\.a by 4\_relax - \_multiply\.a by 2\_relax - \_edef\.alignment_generalskip{\_the\.a}% - % - %Now set \.alignment_firstskip to (\.size-13)-(\.k-2)*\.alignment_generalskip % - \.a = \.k\_relax - \_advance\.a by -2\_relax - \_multiply\.a by -\.alignment_generalskip\_relax - \_advance\.a by \.size\_relax - \_advance\.a by -13\_relax - \_edef\.alignment_firstskip{\_the\.a}% - % - % - % - % Our \.totaldatacodewords bytes of data are broken up as evenly as possible - % into \.numblocks datablocks; some may be one byte longer than others. - % We set \.shortblock_size to floor(\.totaldatacodewords / \.numblocks) - % and \.numlongblocks to mod(\.totaldatacodewords , \.numblocks). - \.a=\.totaldatacodewords\_relax - \_divide\.a by \.numblocks\_relax - \_edef\.shortblock_size{\_the\.a}% - \_multiply\.a by -\.numblocks\_relax - \_advance\.a by \.totaldatacodewords\_relax - \_edef\.numlongblocks{\_the\.a}% - % - %Set \.longblock_size to \.shortblock_size+1. - \.a=\.shortblock_size\_relax - \_advance\.a by 1\_relax - \_edef\.longblock_size{\_the\.a}% - % - %Set \.numshortblocks to \.numblocks - \.numlongblocks - \.b=\.numblocks\_relax - \_advance\.b by -\.numlongblocks\_relax - \_edef\.numshortblocks{\_the\.b}% -}% - -\_def\.settableix_int(#1,#2){% - \_edef\.numblocks{#1}% - \_edef\.numeccodewords{#2}% -}% - -\_def\.settableix{% -\_ea\_ifcase\.level\_relax - %00: Level 'M', medium error correction - \_edef\.tempdata{(% - \_ifcase\.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\.tempdata{% - (\_ifcase\.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\.tempdata{(% - \_ifcase\.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\.tempdata{(% - \_ifcase\.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 -\_ea\.settableix_int\.tempdata -}% - -\_def\.qM{M}\_def\.qz{0}% -\_def\.qL{L}\_def\.qi{1}% -\_def\.qH{H}\_def\.qii{2}% -\_def\.qQ{Q}\_def\.qiii{3}% -\_def\.setlevel#1{% - \_edef\.level_selected{#1}% - \_ifx\.level_selected\.qM - \_edef\.desiredlevel{0}% - \_fi - \_ifx\.level_selected\.qL - \_edef\.desiredlevel{1}% - \_fi - \_ifx\.level_selected\.qH - \_edef\.desiredlevel{2}% - \_fi - \_ifx\.level_selected\.qQ - \_edef\.desiredlevel{3}% - \_fi - \_ifx\.level_selected\.qz - \_edef\.desiredlevel{0}% - \_fi - \_ifx\.level_selected\.qi - \_edef\.desiredlevel{1}% - \_fi - \_ifx\.level_selected\.qii - \_edef\.desiredlevel{2}% - \_fi - \_ifx\.level_selected\.qiii - \_edef\.desiredlevel{3}% - \_fi -}% - -% key-value pairs (OPmac trick 0069) -\_def\.kv#1{\_ifcsname _qr_kv:#1\_endcsname \_csname _qr_kv:#1\_ea\_endcsname - \_else \_ea\.kvunknown \_fi -} -\_def\.kvunknown{???} -\_def\.kvscan #1#2=#3,{\_ifx#1,\_else \_sdef{_qr_kv:#1#2}{#3}\_ea\.kvscan\_fi} - -\_def\.qrset#1{\_def\.tmpb{#1,}% - \_replstring\.tmpb{ =}{=}\_replstring\.tmpb{= }{=}% - \_replstring\.tmpb{tight,}{qr-border=0,}% - \_replstring\.tmpb{padding,}{qr-border=1,}% - \_replstring\.tmpb{verbose,}{qr-message=1,}% - \_replstring\.tmpb{silent,}{qr-message=0,}% - \_replstring\.tmpb{draft,}{qr-final=0,}% - \_replstring\.tmpb{final,}{qr-final=1,}% - \_replstring\.tmpb{nolink,}{qr-link=0,}% - \_replstring\.tmpb{link,}{qr-link=1,}% - \_ea\.kvscan\.tmpb,=,% - \.desiredheight=\.kv{height}\_relax - \.setlevel{\.kv{level}}% - \_edef\.desiredversion{\.kv{version}}% -} -\.qrset{height=2cm, version=0, level=M, tight, silent, final, nolink} - -\_def\.setcounter #1#2{\_global#1=#2\_relax} -\_def\.stepcounter #1{\_global\_advance#1 by1\_relax} -\_def\.addtocounter#1#2{\_global\_advance#1 by#2\_relax} - -\_def\.qrcode{\_begingroup - \_isnextchar[{\.qrcodeA}{\.qrcodeB}% -} -\_def\.qrcodeA[#1]{\.qrset{#1}\_ea\.qrcodeB\_romannumeral-`\.} -\_def\.qrcodeB#1{% - \_if1\.kv{qr-message}\_let\.message=\_message \_else \_def\.message##1{}\_fi - \_if1\.kv{qr-border}\_def\.padd{\_kern4\.modulesize}\_else\_def\.padd{}\_fi - \_bgroup - \_escapechar=-1 - \_xdef\.etext{\_detokenize{#1}}\_gdef\.text{#1}% - \_egroup - \.qrcode_int - \_endgroup -} -\_def\.qrcode_int{% - \.message{<QR code requested for "\.etext" in version - \.desiredversion-\.level_char{\.desiredlevel}.>^^J}% - %First, choose the version and level. - %Recall that \.choose_bestversion sets \.version and \.level. - \_ea\.choose_bestversion\_ea{\.etext}% - \_if1\.kv{qr-final}% - \.setversion{\.version}{\.level}% - \.qrcode_int_new - \_else - \.modulesize=\.desiredheight - \_divide\.modulesize by \.size\_relax - \_let\.d=\.desiredheight - \_vbox{\.padd\_hbox{\.padd\_vbox to\.d{\_hrule\_vss - \_hbox to\.d{\_vrule height.7\.d depth.3\.d \_hss ...QR...\_hss\_vrule}% - \_vss\_hrule}\.padd}\.padd}% - \_fi -}% - -\_nspublic \qrcode \qrset ; - -\_def\.qrcode_int_new{% - \.qrbeginhook - \.createsquareblankmatrix{newqr}{\.size}% - \.placefinderpatterns{newqr}% - \.placetimingpatterns{newqr}% - \.placealignmentpatterns{newqr}% - \.placedummyformatpatterns{newqr}% - \.placedummyversionpatterns{newqr}% - \.message{<Calculating QR code for "\.etext" in - version \.version-\.level_char{\.level}.>^^J}% - \_ea\.encode_binary\_ea{\.etext}% - \.splitcodetextintoblocks - \.createerrorblocks - \.interleave - \.message{<Writing data...}% - \.writedata_hex{newqr}{\.interleaved_text}% - \.message{done.>^^J}% - \.writeremainderbits{newqr}% - \.chooseandapplybestmask{newqr}% - \.decimaltobinary[2]{\.level_binary}{\.level}% - \.decimaltobinary[3]{\.mask_binary}{\.mask_selected}% - \_edef\.formatstring{\.level_binary\.mask_binary}% - \.message{<Encoding and writing format string...}% - \_ea\.encodeandmaskformat\_ea{\.formatstring}% - \.writeformatstring{newqr}{\.formatbitstring}% - \.message{done.>^^J}% - \.message{<Encoding and writing version information...}% - \.decimaltobinary[6]{\.version_binary}{\.version}% - \.Golaycode{\.version_binary}% - \.writeversionstring{newqr}{\.Golayresult}% - \.message{done.>^^J}% - \.message{<Printing QR code...}% - \.matrixtobinary{newqr}% - \.restore\.data - \.message{done.>^^J}% - \.qrendhook -}% - -\_def\.matrixtobinary#1{% - \_bgroup - \_gdef\.data{}% - \_def\.black{1}\_let\.blackfixed=\.black \_let\.blackformat=\.black - \_def\.white{0}\_let\.whitefixed=\.white \_let\.whiteformat=\.white - \.for \.iz = 1 to \.size by 1 - {\.for \.jz = 1 to \.size by 1 - {\_xdef\.data{\.data\.matrixentry{#1}{\_the\.iz}{\_the\.jz}}}}% - \_xdef\.data{{\.size}{\.data}}% - \_egroup -} - -\_def\.restore#1{\_ea\.restoreA#1} -\_def\.restoreA#1#2{% - \.modulesize=\.desiredheight \_divide\.modulesize by#1 - \_if1\.kv{qr-link}\_setbox0=\_fi - \_vbox\_bgroup\.padd \_offinterlineskip \_baselineskip=\.modulesize - \.i=0 \.j=0 \_let\.next=\.restoreB - \_hbox\_bgroup\.padd \.restoreB #2% - \_if1\.kv{qr-link}\.link{\.etext}{\_box0}\_fi -} -\_def\.restoreB#1{\_advance \.j by1 - \_ifx1#1\_vrule height\.modulesize width\.modulesize\_else \_kern\.modulesize\_fi - \_ifnum\.size=\.j \_vrule height\.modulesize width 0pt \.padd\_egroup \_advance\.i by1 - \_ifnum\.size=\.i \.padd\_egroup \_let\.next=\_relax \_else \_hbox\_bgroup\.padd \_fi - \_fi \.next -} - -\_def\.qrbeginhook{} -\_def\.qrendhook{} - -\_endnamespace -\_endcode - -This macro file is created for \OpTeX/. It is derived from: - -\begtt -% qrcode.tex -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Petr Olsak <petr@olsak.net> Jul. 2015 - -% This macro qrcode.tex is (roughly speaking) a copy of qrcode.sty -% macro by Anders Hendrickson <ahendric@cord.edu>, see -% http://www.ctan.org/tex-archive/macros/latex/contrib/qrcode - -% The main difference between qrcode.sty and qrcode.tex is, that -% the LaTeX ballast was removed from qrcode.sty by Petr Olsak. The result: -% The qrcode.tex macro can be used in plain TeX format too. -\endtt - -\secc Usage - -Load this macro file by `\load[qrcode]` and then the command -`\qrcode{<encoded text>}` or `\qrcode[<options>]{<encoded text>}` is ready to use. - -The parameter <encoded text> is used as is (without expanding). -It follows the same rules as in the `\code{<text>}` macro. -Use these rules if the encoded text includes a \TeX/ sensitive characters. - -The characters from all Unicode table are allowed in <encoded text>. - -\secc Options - -You can use `\qrset{<options>}` for global-like options and -`\qrcode[<options>]{<encoded text>}` for local options for one QR code. -The `\qrset{<options>}` is valid within a group (if exists) or in whole -document. - -Options are separated by comma and they are in two types: single -word or key=value format. Default options are: - -\begtt -\qrset{height=2cm, version=0, level=M, tight, silent, final, nolink} -\endtt - -The options are the same as described in `qrcode.pdf` at -\url{http://www.ctan.org/tex-archive/macros/latex/contrib/qrcode}. -In short: - -\begitems -* `height=dimen` ... The height of the QRcode without padding. - -* `version=number` ... Number 0 to 40 linearly depends on the density of QRcode. - The 0 means that the density is automatically selected. - -* `level=letter` ... L, M, Q o H (low, medium, quality, hight) sets the amount - of redundancy in the code in order of error recovering. - -* `tight` ... Code without margins. -* `padding` ... 4module blank margins around the code. - -* `verbose` ... Information about calculating in terminal and in the log. -* `silent` ... No information about calculating. - -* `final` ... The QR code is calculated and printed. -* `draft` ... Only empty rectangle in the same size as QR code is printed. - -* `nolink` ... The QR code is not active hyperlink. -* `link` ... The QR code is active hyperlink to <encoded text>. - -* `qrborder={R G B}` ... The color of the frame around active hypertext space - if link option is set. R G B (red green blue) are decimal - numbers from 0 to 1. The frame is visible only in - pdf viewers. Default: invisible frame. -\enditems - - -Example: - -\begtt -\qrset{silent} % ... all codes will be silent in the log and terminal. -\qrcode [height=3cm, link, padding, qrborder={1 0 0}] {http://petr.olsak.net} - % ... 3cm QRcode as hyperlink -\endtt - -Note: - -The saving/restoring pre-calculated QRcodes isn't supported by default. -If you are printing the same QR codes repeatedly, use \setbox/\copy -technique. For example: - -\begtt -\newbox\mybox -\setbox\mybox=\hbox{\qrcode{encoded text}} -\copy\mybox \copy\mybox \copy\mybox etc. -\endtt - -If you have a huge amount of different QR codes, you can use draft/final -options. - -The `\_qr_data` macro is saved after each \qrcode calculation in the format -`{size}{111101011...001}` where size is the number of columns or rows in QR -square and second parameter includes size^2 ones or zeros which means black -or white modules (scanned left to right, top to bottom). Another information -can be retrieved from `\_qr_text` macro (encoded text before expanding) and -`\_qr_etext` macro (raw encoded text, each charater is detokeinized). -The macros `\_qr_data`, `\_qr_text` and `\_qr_etext` are saved globally. - |