%Author: Ji\v{r}\'{i} Mrkus
%License: LaTeX Project Public License
\newcount\stringlength
\stringlength=0
\newcount\check
\check=0
\newcount\badchar
\badchar=0
\newcount\oddcount
\oddcount=0
\newcount\evencount
\evencount=0
\newcount\helplen
\helplen=0
\newcount\moda
\newcount\modb

\newdimen\module
\newdimen\height
\newdimen\fivemodule
\newdimen\fntsize
\newdimen\unita
\newdimen\unitb
\newdimen\unitc
\newdimen\helpind

\fntsize=12pt
\module=0.33mm
\height=25.9mm



\def\upca#1 {\kern 1.5mm\edef\currfont{\the\font}%
	\helpind=\parindent%
	\parindent=0pt%
	\unita=\module%
	\multiply\unita by1065%
	\divide\unita by1000%
	\unitb=\unita%
	\unitc=\unita%
	\multiply\unita by4%
	\multiply\unitb by11%
	\multiply\unitc by2%
	\fntsize=\module%
	\multiply\fntsize by950%
	\divide\fntsize by100%
	\font\upcafont=ocrb10 at \fntsize%
	\upcafont%
	\fivemodule=\module%
	\multiply\fivemodule by5%
	\stringlength=0 \badchar=0%
	\control[#1] \ifnum\badchar=0 \ifnum\check=1 \controlchar[#1]%
	\hbox{\upcacode[#1{\checkchar}]}\else%
	\hbox{\upcacode[#1]}\fi\else\fi%
	\parindent=\helpind \currfont \kern 1.5mm}



\def\upcacode[#1]{\stringlength=1%
	\advance\height by\fivemodule%
	\ooalign{\split[00000]\split[101] \upcahash[#1]\split[00000]\cr%
	\hbox{\kern-\unitc \lower \unita\hbox{\upcatext[#1]}}}}


%Macro which prints text under the code
\def\upcatext[#1#2]{#1\kern\unitb \sndtext[#2]}
\def\sndtext[#1#2#3#4#5#6]{#1#2#3#4#5\kern\unita \rdtext[#6]}
\def\rdtext[#1#2#3#4#5#6]{#1#2#3#4#5\kern\unitb #6}

%This macro converts number to sequence of 0 and 1
\def\upcahash[#1#2]{%
	\if#10 \ifnum\stringlength=1 \split[0001101]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0001101]}\else%
	\ifnum\stringlength=12 \split[1110010]\else%
	\raise\fivemodule\hbox{\split[1110010]}\fi\fi\fi\else%
	\if#11 \ifnum\stringlength=1 \split[0011001]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\mbox{\split[0011001]}\else%
	\ifnum\stringlength=12 \split[1100110]\else%
	\raise\fivemodule\hbox{\split[1100110]}\fi\fi\fi\else%
	\if#12 \ifnum\stringlength=1 \split[0010011]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0010011]}\else%
	\ifnum\stringlength=12 \split[1101100]\else%
	\raise\fivemodule\hbox{\split[1101100]}\fi\fi\fi\else%
	\if#13 \ifnum\stringlength=1 \split[0111101]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0111101]}\else%
	\ifnum\stringlength=12 \split[1000010]\else%
	\raise\fivemodule\hbox{\split[1000010]}\fi\fi\fi\else%
	\if#14 \ifnum\stringlength=1 \split[0100011]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0100011]}\else%
	\ifnum\stringlength=12 \split[1011100]\else%
	\raise\fivemodule\hbox{\split[1011100]}\fi\fi\fi\else%
	\if#15 \ifnum\stringlength=1 \split[0110001]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0110001]}\else%
	\ifnum\stringlength=12 \split[1001110]\else%
	\raise\fivemodule\hbox{\split[1001110]}\fi\fi\fi\else%
	\if#16 \ifnum\stringlength=1 \split[0101111]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0101111]}\else%
	\ifnum\stringlength=12 \split[1010000]\else%
	\raise\fivemodule\hbox{\split[1010000]}\fi\fi\fi\else%
	\if#17 \ifnum\stringlength=1 \split[0111011]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0111011]}\else%
	\ifnum\stringlength=12 \split[1000100]\else%
	\raise\fivemodule\hbox{\split[1000100]}\fi\fi\fi\else%
	\if#18 \ifnum\stringlength=1 \split[0110111]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0110111]}\else%
	\ifnum\stringlength=12 \split[1001000]\else%
	\raise\fivemodule\hbox{\split[1001000]}\fi\fi\fi\else%
	\if#19 \ifnum\stringlength=1 \split[0001011]\else%
	\ifnum\stringlength<7%
	\raise\fivemodule\hbox{\split[0001011]}\else%
	\ifnum\stringlength=12 \split[1110010]\else%
	\raise\fivemodule\hbox{\split[1110100]}\fi\fi\fi \else \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
	\ifnum\stringlength=11 \advance\height by\fivemodule\else\fi%
	\ifnum\stringlength=6%
		\advance\height by\fivemodule%
		\split[01010]%
		\advance\height by-\fivemodule \else \fi%		
	\ifnum\stringlength=1 \advance\height by-\fivemodule \else\fi%
	\advance\stringlength by1%
	\if:#2: \split[101]%
	\advance\height by-\fivemodule%
	\else\upcahash[#2]\fi}

%Macro takes as parameter sequence of 0 and 1, every character passes on draw macro
\def\split[#1#2]{\draw[#1] \if:#2: \else \split[#2] \fi}

%This macro takes as parameter one character (0 or 1) and draws a bar or space
\def\draw[#1]{\if#11\vrule height \height width \module \else \if#10\hskip \module \fi \fi}

%Returns true if character in parameter is a digit, false otherwise
\newif\ifnext
\def\ifdigit[#1]{\ifnum`#1>47 \ifnum`#1<58 \nexttrue\else\nextfalse\fi\else\nextfalse\fi\ifnext}

%This macro computes length of string in parameter - result is in helplen register
\def\strlen[#1#2]{\if:#2: \advance\helplen by1 \else \advance\helplen by1\strlen[#2]\fi}

%Macro which computes modulo of two numbers in moda and modb registers - result in moda
\def\modulo{%
	\ifnum\moda>\modb \advance\moda by-\modb \modulo%
	\else \fi\ifnum\moda=\modb \moda=0 \else \fi}

%Macro which controls if parameter has length 11 or 12 characters and contains only digits
\def\control[#1#2]{\ifdigit[#1]\advance\stringlength by1%
	\if:#2: \ifnum\stringlength=11 \check=1 \else%
	\ifnum\stringlength=12 \check=0%
	\else \message{String must have 11 or 12 characters}\badchar=1\fi\fi\else\control[#2]\fi%
	\else \message{Invalid characters: code can contain only digits}\badchar=1\fi}

%Macro which computes the check digit
\def\controlchar[#1#2]{\helplen=0 \if:#2: \else \strlen[#2]\fi \moda=\helplen \modb=2 \modulo%
	\ifnum\moda=0 \advance\oddcount by`#1 \advance\oddcount by-48 \else%
	\advance\evencount by`#1 \advance\evencount by-48 \fi%
	\ifnum\helplen>0 \controlchar[#2]\else%
	\multiply\oddcount by3 \advance\oddcount by\evencount \moda=\oddcount \modb=10 \modulo%
	\ifnum\moda=0 \check=0 \else \check=10 \advance\check by-\moda\fi \def\checkchar{\the\check}\fi}

\endinput
.
