diff --git a/doc/user/methods.rst b/doc/user/methods.rst index 247d9cc..055c3b0 100644 --- a/doc/user/methods.rst +++ b/doc/user/methods.rst @@ -36,7 +36,7 @@ barcode("code", "barcode\_type", width, height, "position", "font") Prints a barcode. * ``code`` is an alphanumeric code to be printed as bar code -* ``barcode_type`` must be one of the following type of codes: +* ``barcode_type`` must be one of the following type of codes for function type A: * UPC-A * UPC-E @@ -45,7 +45,19 @@ Prints a barcode. * CODE39 * ITF * NW7 - + + And for function type B: + + * Any type above + * CODE93 + * CODE128 + * GS1-128 + * GS1 DataBar Omnidirectional + * GS1 DataBar Truncated + * GS1 DataBar Limited + * GS1 DataBar Expanded + + * ``width`` is a numeric value in the range between (1,255) *Default:* 64 * ``height`` is a numeric value in the range between (2,6) *Default:* 3 * ``position`` is where to place the code around the bars, could be one of the following values: @@ -58,7 +70,14 @@ Prints a barcode. * ``font`` is one of the 2 type of fonts, values could be: * A - * B > *Default:* A Raises ``BarcodeTypeError``, ``BarcodeSizeError``, ``BarcodeCodeError`` exceptions. + * B > *Default:* A + +* ``fuction_type`` chooses between ESCPOS function type A or B. A is default, B has more barcode options. Choose which one based upon your printer support and require barcode. + + * A + * B > *Default* A + +* Raises ``BarcodeTypeError``, ``BarcodeSizeError``, ``BarcodeCodeError`` exceptions. text("text") ^^^^^^^^^^^^ diff --git a/escpos/constants.py b/escpos/constants.py index d1835a4..4274fbe 100644 --- a/escpos/constants.py +++ b/escpos/constants.py @@ -126,17 +126,51 @@ BARCODE_WIDTH = GS + 'w' # Barcode Width [2-6] #NOTE: This isn't actually an ESC/POS command. It's the common prefix to the # two "print bar code" commands: -# - "GS k NUL" -# - "GS k " +# - Type A: "GS k NUL" +# - TYPE B: "GS k " # The latter command supports more barcode types _SET_BARCODE_TYPE = lambda m: GS + 'k' + m -BARCODE_UPC_A = _SET_BARCODE_TYPE('\x00') # Barcode type UPC-A -BARCODE_UPC_E = _SET_BARCODE_TYPE('\x01') # Barcode type UPC-E -BARCODE_EAN13 = _SET_BARCODE_TYPE('\x02') # Barcode type EAN13 -BARCODE_EAN8 = _SET_BARCODE_TYPE('\x03') # Barcode type EAN8 -BARCODE_CODE39 = _SET_BARCODE_TYPE('\x04') # Barcode type CODE39 -BARCODE_ITF = _SET_BARCODE_TYPE('\x05') # Barcode type ITF -BARCODE_NW7 = _SET_BARCODE_TYPE('\x06') # Barcode type NW7 + +# Barcodes for printing function type A +BARCODE_TYPE_A = { + 'UPC-A': _SET_BARCODE_TYPE(chr(0)), + 'UPC-E': _SET_BARCODE_TYPE(chr(1)), + 'EAN13': _SET_BARCODE_TYPE(chr(2)), + 'EAN8': _SET_BARCODE_TYPE(chr(3)), + 'CODE39': _SET_BARCODE_TYPE(chr(4)), + 'ITF': _SET_BARCODE_TYPE(chr(5)), + 'NW7': _SET_BARCODE_TYPE(chr(6)), + 'CODABAR': _SET_BARCODE_TYPE(chr(6)), # Same as NW7 +} + +# Barcodes for printing function type B +# The first 8 are the same barcodes as type A +BARCODE_TYPE_B = { + 'UPC-A': _SET_BARCODE_TYPE(chr(65)), + 'UPC-E': _SET_BARCODE_TYPE(chr(66)), + 'EAN13': _SET_BARCODE_TYPE(chr(67)), + 'EAN8': _SET_BARCODE_TYPE(chr(68)), + 'CODE39': _SET_BARCODE_TYPE(chr(69)), + 'ITF': _SET_BARCODE_TYPE(chr(70)), + 'NW7': _SET_BARCODE_TYPE(chr(71)), + 'CODABAR': _SET_BARCODE_TYPE(chr(71)), # Same as NW7 + 'CODE93': _SET_BARCODE_TYPE(chr(72)), + # These are all the same barcode, but using different charcter sets + 'CODE128A': _SET_BARCODE_TYPE(chr(73) + '{A'), # CODE128 character set A + 'CODE128B': _SET_BARCODE_TYPE(chr(73) + '{B'), # CODE128 character set B + 'CODE128C': _SET_BARCODE_TYPE(chr(73) + '{C'), # CODE128 character set C + 'GS1-128': _SET_BARCODE_TYPE(chr(74)), + 'GS1 DATABAR OMNIDIRECTIONAL': _SET_BARCODE_TYPE(chr(75)), + 'GS1 DATABAR TRUNCATED': _SET_BARCODE_TYPE(chr(76)), + 'GS1 DATABAR LIMITED': _SET_BARCODE_TYPE(chr(77)), + 'GS1 DATABAR EXPANDED': _SET_BARCODE_TYPE(chr(78)), +} + +BARCODE_TYPES = { + 'A': BARCODE_TYPE_A, + 'B': BARCODE_TYPE_B, +} + # Image format # NOTE: _PRINT_RASTER_IMG is the obsolete ESC/POS "print raster bit image" diff --git a/escpos/escpos.py b/escpos/escpos.py index 8944633..62c90b1 100644 --- a/escpos/escpos.py +++ b/escpos/escpos.py @@ -314,12 +314,13 @@ class Escpos(object): else: raise CharCodeError() - def barcode(self, code, bc, height=64, width=3, pos="BELOW", font="A", align_ct=True): + def barcode(self, code, bc, height=64, width=3, pos="BELOW", font="A", align_ct=True, function_type="A"): """ Print Barcode This method allows to print barcodes. The rendering of the barcode is done by the printer and therefore has to be supported by the unit. Currently you have to check manually whether your barcode text is correct. Uncorrect - barcodes may lead to unexpected printer behaviour. + barcodes may lead to unexpected printer behaviour. There are two forms of the barcode function. Type A is + default but has fewer barcodes, while type B has some more to choose from. .. todo:: Add a method to check barcode codes. Alternatively or as an addition write explanations about each barcode-type. Research whether the check digits can be computed autmatically. @@ -340,7 +341,7 @@ class Escpos(object): be of help if the printer does not support types that others do.) :param code: alphanumeric data to be printed as bar code - :param bc: barcode format, possible values are: + :param bc: barcode format, possible values are for type A are: * UPC-A * UPC-E @@ -350,6 +351,17 @@ class Escpos(object): * ITF * NW7 + Possible values for type B: + + * All types from function type A + * CODE93 + * CODE128 + * GS1-128 + * GS1 DataBar Omnidirectional + * GS1 DataBar Truncated + * GS1 DataBar Limited + * GS1 DataBar Expanded + If none is specified, the method raises :py:exc:`~escpos.exceptions.BarcodeTypeError`. :param height: barcode height, has to be between 1 and 255 *default*: 64 @@ -373,6 +385,10 @@ class Escpos(object): issued. :type align_ct: bool + :param function_type: Choose between ESCPOS function type A or B, depending on printer support and desired + barcode. + *default*: A + :raises: :py:exc:`~escpos.exceptions.BarcodeSizeError`, :py:exc:`~escpos.exceptions.BarcodeTypeError`, :py:exc:`~escpos.exceptions.BarcodeCodeError` @@ -404,29 +420,29 @@ class Escpos(object): self._raw(BARCODE_TXT_ABV) else: # DEFAULT POSITION: BELOW self._raw(BARCODE_TXT_BLW) - # Type - if bc.upper() == "UPC-A": - self._raw(BARCODE_UPC_A) - elif bc.upper() == "UPC-E": - self._raw(BARCODE_UPC_E) - elif bc.upper() == "EAN13": - self._raw(BARCODE_EAN13) - elif bc.upper() == "EAN8": - self._raw(BARCODE_EAN8) - elif bc.upper() == "CODE39": - self._raw(BARCODE_CODE39) - elif bc.upper() == "ITF": - self._raw(BARCODE_ITF) - elif bc.upper() in ("NW7", "CODABAR"): - self._raw(BARCODE_NW7) - else: - raise BarcodeTypeError(bc) + + bc_types = BARCODE_TYPES[function_type.upper()] + if bc.upper() not in bc_types.keys(): + # TODO: Raise a better error, or fix the message of this error type + raise BarcodeTypeError("Barcode type {bc} not valid for barcode function type {function_type}".format( + bc=bc, + function_type=function_type, + )) + + self._raw(bc_types[bc.upper()]) + + if function_type.upper() == "B": + self._raw(chr(len(code))) + # Print Code if code: self._raw(code) else: raise BarcodeCodeError() + if function_type.upper() == "A": + self._raw("\x00") + def text(self, txt): """ Print alpha-numeric text