From b56053148d9bd15dfefb765f19113681cd75a654 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 30 Jun 2018 16:24:42 +0300 Subject: Add: code128.tex --- code128.tex | 360 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 code128.tex diff --git a/code128.tex b/code128.tex new file mode 100644 index 0000000..1f8844c --- /dev/null +++ b/code128.tex @@ -0,0 +1,360 @@ +% Macro for conversion of string to barcodes by Code 128 standard +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% March 1996 (C) Petr Ol\v{s}\'ak + +% For user information see the file test128.tex + +% Comments at programmer level are included in this file. First you can +% read the end of this file: The description of Code 128 standard. + +\wlog{**** Macro for barcodes in "Code 128" by (C) Petr Olsak used ****} + +% Declarations: +\newdimen\X % the module size X, +\newdimen\bcorr % the bar correction (see bellow). +\newdimen\workdimen \newdimen\barheight % internal variables +\newtoks\inputtext \newtoks\icode +\newcount\tempnum \newcount\chnum \newcount\chtotal +\newif\ifnext \newif\ifchar +\def\empty{} \def\End{@@end} + +% Implicit values: +\X=.33mm % The X module width. +\bcorr=.020mm % Bar reduction. +\barheight=1.5cm % The code height. + +% First we declare some tables. +% "\definetable string \relax": Each token from "string" gets a value +% (spaces are ignored). First token gets value , second +% and so on. It is possible to reconstruct the value by +% "\csname\string\endcsname". +\def\definetable#1#2 {\tempnum=#2 \def\temp{#1}\let\next=\repeatdefine \next} +\def\repeatdefine#1{\ifx#1\relax \let\next=\relax \else + \expandafter\edef\csname\temp\string#1\endcsname{\the\tempnum}% + \advance\tempnum by1 \fi \next} + +%%%%%%%%%%%%%%%%%%%%% Basic tables for Code 128: %%%%%%%%%%%%%%%%%%%%%%%%%%% +\definetable:0 % All input characters from Code B: + \ ! " \# \$ \% \& ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ + 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 [ \\ ] \^ \_ ` + 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 \{ | \} \~ \DEL \relax +\definetable:64 % Other input characters from Code A: + \NUL \SOH \STX \ETX \EOT \ENQ \ACK \BEL \BS \HT \LF \VT \FF \CR \SO \SI + \DLE \DCone \DCtwo \DCthree \DCfour \NAK \SYN \ETB \CAN \EM \SUB \ESC + \FS \GS \RS \US \relax +\definetable:0 \ + \relax % the \^^M must be the same as \ +\definetable:0 \SP \relax % the \SP is alternative to \ +\definetable{D:}0 0123456789 \relax % Digits +\definetable{B:}0 `abcdefghijklmnopqrstuvwxyz\{\|\}\~ \relax % Only in Code B +\definetable{A:}0 \NUL \SOH \STX \ETX \EOT \ENQ \ACK \BEL \BS \HT \LF \VT + \FF \CR \SO \SI \DLE \DCone \DCtwo \DCthree \DCfour \NAK \SYN \ETB \CAN + \EM \SUB \ESC \FS \GS \RS \US \relax % only in code A. +\def\tableofcode#1{\ifcase#1 % The output characters: + 212222\or 222122\or 222221\or 121223\or 121322\or % 0-4 + 131222\or 122213\or 122312\or 132212\or 221213\or % 5-9 + 221312\or 231212\or 112232\or 122132\or 122231\or % 10-14 + 113222\or 123122\or 123221\or 223211\or 221132\or % 15-19 + 221231\or 213212\or 223112\or 312131\or 311222\or % 20-24 + 321122\or 321221\or 312212\or 322112\or 322211\or % 25-29 + 212123\or 212321\or 232121\or 111323\or 131123\or % 30-34 + 131321\or 112313\or 132113\or 132311\or 211313\or % 35-39 + 231113\or 231311\or 112133\or 112331\or 132131\or % 40-44 + 113123\or 113321\or 133121\or 313121\or 211331\or % 45-49 + 231131\or 213113\or 213311\or 213131\or 311123\or % 50-54 + 311321\or 331121\or 312113\or 312311\or 332111\or % 55-59 + 314111\or 221411\or 431111\or 111224\or 111422\or % 60-64 + 121124\or 121421\or 141122\or 141221\or 112214\or % 65-69 + 112412\or 122114\or 122411\or 142112\or 142211\or % 70-74 + 241211\or 221114\or 413111\or 241112\or 134111\or % 75-79 + 111242\or 121142\or 121241\or 114212\or 124112\or % 80-84 + 124211\or 411212\or 421112\or 421211\or 212141\or % 85-89 + 214121\or 412121\or 111143\or 111341\or 131141\or % 90-94 + 114113\or 113311\or 411113\or 411311\or 113141\or % 95-99 + 114131\or 311141\or 411131\else 00000\fi } % 100-102 +\def\startA{211412} +\def\startB{211214} +\def\startC{211232} +\def\stop{23311120} + +% Implementations of tests: +% After "\testchar " the "\ifchar" has following meaning: +% true, if is in digits, only in A or only in B respectively with +% is {D:}, {A:} or {B:}. +\def\testchar #1#2{\expandafter\ifx\csname#1\string#2\endcsname \relax + \charfalse \else \chartrue \fi} + +% After "\numofdigits string\stop" is used, the \tempnum register contain +% the number of digits from first continuosly group of digits from left in +% "string". If "string" starts with no digit then \tempnum=0. +\def\numofdigits{\tempnum=0 \let\next=\cyklnumber \cyklnumber} +\def\cyklnumber#1{\testchar {D:}#1% + \ifchar \advance\tempnum by1 + \else \ifx #1\stop\def\next{}% + \else \def\next##1\stop{}\fi + \fi \next} + +% After "\testnext string\stop" is used, the "\ifnext" has +% the following meaning: +% 1. is {A:}: "\ifnext" is true, if first character from "string" is +% only in A code after skip all common characters shared in codeA and B. +% 2. is {B:}: "\ifnext" is true, if first character from "string" is +% only in B code after skip all common characters shared in codeA and B. +\def\testA{A:} +\def\testnext#1{\nextfalse + \def\tempA{#1}% + \ifx\tempA\testA \def\tempB{B:}\else \def\tempB{A:}\fi + \let\next=\cyklcontrol \next} +\def\cyklcontrol#1{% + \ifx#1\stop \let\next=\relax + \else \testchar \tempB #1% + \ifchar \def\next##1\stop{}% + \else \testchar \tempA #1% + \ifchar \nexttrue \def\next##1\stop{}\fi \fi + \fi \next} + +% "\addtok \cs" adds the "\cs," into \icode. +% "\addtoks{string} adds the "string," into \icode. "string" is the number +% of line in table 1, so we re-calculate the current check sum. +% "\addchar adds the numerical value of (declared in +% \definetable:) into \icode. This value is followed by comma too. +\def\addtok#1{\edef\act{\noexpand\icode={\the\icode\noexpand#1,}}\act} +\def\addtoks#1{\edef\act{\noexpand\icode={\the\icode#1,}}\act + \tempnum=#1 \multiply\tempnum by\chnum + \advance\chtotal by\tempnum \advance\chnum by 1\relax} +\def\addchar#1{\expandafter\ifx\csname:\string#1\endcsname\relax + \errmessage{The input token "\string#1" is not included in Code 128 + table, will ignored}% + \else \expandafter\addtoks\expandafter{\csname:\string#1\endcsname}\fi} + +% \code{text} first converts the input text into internal representation in +% \icode. The format of \icode is: "\start,num,num,num,\stop,", where +% "\start" is one of "\startA" or "\startB" or "\startC". The +% represents the line of code table (see standard of Code 128 bellow) +% of output characters. The amount of s is not restricted. The sequence +% is terminated by "\stop,". See to .log for example of this format. +% +% The choice of the start character: +% If next 4 input characters are digits then \startC +% else if the next uncommon char is from code A and not from B then \startA +% else \startB +% The "next uncommon char" is first character from left which falls +% into code A xor code B +\def\code#1{\inputtext={#1}\wlog{** Code 128 ** input: \the\inputtext}% + \icode={}\chnum=1 + \numofdigits#1\stop % in \tempnum is the number of digits now + \ifnum\tempnum>3 \addtok\startC \chtotal=2 \let\Next=\codeC \else + \testnext{A:} #1\stop + \ifnext \addtok\startA \chtotal=0 \let\Next=\codeA + \else \addtok\startB \chtotal=1 \let\Next=\codeB \fi + \fi \Next #1\End\End} + +% There is mode A. Test to change the mode: +% If the next 4 input characters are digits and the number of digits are even +% then switch to modeC using . +% If the next char is from Code B and not from Code A then: +% if the next uncommnon char is from Code B and not from A then +% switch to mode B using . +% else include and stay in mode A. +\def\codeA #1#2#3\End{\addchar#1% + \numofdigits#2#3\stop + \ifnum\tempnum>3 \ifodd\tempnum\else + \addtoks{99}\let\Next=\codeC \fi + \else \ifx#2\End \let\Next=\finalcode + \else \testchar{B:} #2% + \ifchar \testnext{B:} #3\stop + \ifnext \addtoks{100}\let\Next=\codeB + \else \addtoks{98}\fi \fi \fi \fi + \Next #2#3\End} + +% There is mode B. Test to change the mode: +% If the next 4 input characters are digits and the number of digits are even +% then switch to modeC using +% If the next char is from Code A and not from Code B then: +% if the next uncommnon char is from Code A and not from B then +% switch to mode A using . +% else include and stay in mode B. +\def\codeB #1#2#3\End{\addchar#1% + \numofdigits#2#3\stop + \ifnum\tempnum>3 \ifodd\tempnum\else + \addtoks{99}\let\Next=\codeC \fi + \else \ifx#2\End \let\Next=\finalcode + \else \testchar{A:} #2% + \ifchar \testnext{A:} #3\stop + \ifnext \addtoks{101}\let\Next=\codeA + \else \addtoks{98}\fi \fi \fi \fi + \Next #2#3\End} + +% There is mode C. Test to change the mode: +% If not next two chars are digits switch to code A or B by following rule: +% If the next uncommon char is from Code A and not from B then +% switch to mode A using +% else switch to mode B using +\def\codeC #1#2#3#4\End{\addtoks{#1#2}% + \ifx#3\End \let\Next=\finalcode + \else \testchar{D:} #3% + \ifchar \def\temp{#4}% + \ifx\temp\empty \switchtoAorB #3\stop + \else \separate #4\stop + \edef\act{\noexpand\testchar{D:}\temp}\act + \ifchar + \else \switchtoAorB #3#4\stop \fi \fi + \else \switchtoAorB #3#4\stop \fi + \fi \Next #3#4\End} +\def\separate#1#2\stop{\def\temp{#1}} +\def\switchtoAorB #1\stop{\testnext{A:} #1\stop + \ifnext \addtoks{101}\let\Next=\codeA + \else \addtoks{100}\let\Next=\codeB \fi} + +\def\finalcode\End\End{\addchecksum \addtok\stop \wlog{encoded: \the\icode}% + \expandafter\makecode\the\icode} + +% \addchecksum adds the check sum into \icode +\def\addchecksum{\tempnum=\chtotal + \divide\tempnum by 103 \multiply\tempnum by 103 + \advance\chtotal by-\tempnum \addtoks{\the\chtotal}} + +% The \makecode converts the \icode from format "\start,num,num,\stop," +% into sequence of digits. Each digit repersents the multiple of X module +% size for bar or space if it is at odd or even position. For example +% 21141223311120. It means bar of 2X, space 1X, bar 1X, space 4X and so on. +% This representation of code is stored in macro \internalcode. +\def\makecode#1,{\let\next=\cyklcode \edef\internalcode{#1}\next} +\def\cyklcode#1,{% + \ifx\stop#1\let\next=\finalmakecode \edef\internalcode{\internalcode\stop}% + \else \edef\internalcode{\internalcode\tableofcode{#1}}\fi \next} +\def\finalmakecode{\wlog{black-white: \internalcode}% + \begcode \let\next=\makebars \expandafter\makebars\internalcode} + +% \makebars simply makes the \vrules and \kerns of appropriate sizes from +% \internalcode representation. Each width of \vrule is corrected by \bcorr +% and opposite for \kern. +\def\makebars#1#2{\if0#2\let\next=\endcode\fi + \workdimen=#1\X \advance\workdimen by-\bcorr \vrule width\workdimen + \workdimen=#2\X \advance\workdimen by \bcorr \kern\workdimen + \next} + +% The begin and end of completed \hbox: +\def\begcode{\hbox\bgroup\vrule height\barheight width0pt} +\def\endcode{\egroup} + +% User can use \codetext or \codeothertext instead \code: +\def\codeothertext#1#2{\vbox{\halign{\hfil##\hfil\cr\code{#1}\cr{\tt#2}\cr}}} +\def\codetext#1{\codeothertext{#1}{#1}} + +\endinput %%%%%%%%%%%%%%% End of macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + The description of Code 128 standard + ************************************ + +The characters from input string are converted from left to right +to so called "output characters" by table 1 (see below). Each output +character has three bars and spaces. The width of bars and the dimensions +of spaces between bars are significant. This values are expresed by +multiples of basic dimension: so called X module size (see \X in macro). +The multiples varies from 1 to 4. We are using the six digits expression of +output character. It expressed dimensions of bar, space, bar, space, bar, +space. For example 122412 means one output character drawn as: 1X bar, 2X +space, 2X bar, 4X space, 1X bar and 2X space. + +The table 1: + +num.line code A code B codeC output character +------------------------------------------------------- + 0 [space] [space] 00 212222 + 1 ! ! 01 222122 + 2 " " 02 222221 + 3 # # 03 121223 +... and so on ... + 63 _ _ 63 111224 + 64 \NUL ` 64 111422 + 65 \SOH a 65 121124 + 66 \STX b 66 121421 +... and so on ... + 93 \GS } 93 111341 + 94 \RS ~ 94 131141 + 95 \US \DEL 95 114113 + 96 96 113311 + 97 97 411113 + 98 98 411311 + 99 99 113141 +100 114131 +101 311141 +102 411131 + +The whole table is not presented here because you can simply reconstruct it +from macros. + +The columns "code A", "code B", and "code C" inlude all possible input +characters in input string (excluding "special commands" in lines 96--102 +written in braces). The special \TeX{} characters must be escaped +(i.e. user have to write \# and no #). The escaped words (in capitals) +represents so called "control characters" from ASCII. The meaning of this +sequences depends on application. The "special commands" in lines 96--102 +written in braces are not possible in input. They are special for +decoder. The and are used in our macro, but are +not because they are reserved for special purposes. + +The Code B column is whole expressed in \definetable:0 (see in macro). The +Code A column has the same values in lines 0--63 (capitals, digits and some +other ASCII characters are included here). Code A differ from Code B in +lines 64--102. The lowercase letters and another ASCII characters are +included in "Code B", but control sequences are included in "Code A". +The different part of "Code A" column is expressed in \definetable:64 (see +in macro). The "code C" column includes the digits pairs and corresponds to +number of line in table 1. Two digits in input go to one output character. +The whole "output character" column is expressed in \tableofcode (see in +macro). + +The "start character" is appended before each barcode. There are three +types of start character depending on which column of table is used for +next encoding (so called mode). See macros \startA, \startB and \startC. +For examlpe: If \startC is used, next output character represents two +digits in input (codeC mode). If \startB is used, next output character +represents one ASCII character in input (codeB mode). If \startA is used, +next output character represents probably the control sequence in input or +capitals, but not lowercase ASCII (codeA mode). + +If some mode for encoding is currently used and next input character is not +included in appropriate column, the "switching command" is included into +sequence of output character. The command switches from mode A to +B or from B to A only for one next input character and the other input +characters are coded in the same mode (A or B). The command +switches to codeA mode definitively unless next switch command is used. +The commands and makes the same service, but to switch into +mode B or C respectively. All these commands are expessed in table 1. + +It is recomended to chose the start character and switching commands by the +way, that the resulting length of code is minimised. There are some +recommendations of this choice. These recommendations are included into our +macros (see the commnets and macros for \code, \codeA, \codeB and \codeC). + +The checksum character is added after the end of input string. Finally, +the "stop character" is appended after the end of barcode. This character +has exclusively four bars and not only three. See macro \stop. + +The checksum character is calculated from output characters used in the +code. The number of line in table 1 of each output character is asumed. The +start character is covered too, but checksum character itself and the +stop character are not included into calculation. The startA or startB or +startC characters has its number of line 103 or 104 or 105 respectively. Each +output character (more exactly its number of line in table 1) is multiplied +by "weight number" and the total sum is calculated. The weight number of +start character is one. The weight number of first output characet after +start is one too. Second character has weight number two, and so on. The +n-th character has weight number n. The total sum modulo 103 is the line of +the calculated checksum character. + +Example for checksum calculation: +Input: 123456 +Encoded: StartC, 12, 34, 56 +Total sum of checksum: 105 + 1*12 + 2*34 + 3*56 = 535 +Modulo 103: 44 +The character from line 44 is apended as checksum. +The whole encoded code: StartC, 12, 34, 56, 44, Stop + +%%% End of file. + + + + -- cgit v1.2.1