zpl.tools
Bar codes

^BM - MSI Bar Code

Plessey-derived numeric symbology with four selectable check-digit schemes, used on library and retail shelf labels.

^BM prints an MSI symbol, a pulse-width-modulated variant of ^BP Plessey. It occurs on library books and retail shelf edges. The choice of four check-digit schemes distinguishes MSI from its neighbors. That choice is not cosmetic. Each scheme encodes different digits, and a symbol with the wrong scheme scans to the wrong number instead of a failure.

Syntax

^BMo,e,h,f,g,e2

Support

Supportedparsed: full · state: full · rendered: full

Every documented parameter renders the same output Labelary produces.

Labelary renders this command.

Parameters

oBar code orientationoptional · one of a set

Rotation of the symbol and interpretation line.

Default
the orientation set by ^FW, which itself defaults to N
Invalid value
discarded, and the default applies. The renderer reports an unrecognized character as invalid, and uses the default.
Test coverage
No documented value is exercised by a test (N, R, I, B). The invalid-value rule is not pinned by a test.
N
No rotation (default)
R
Rotated 90° clockwise
I
Rotated 180°. The symbol reads upside down
B
Rotated 270° clockwise
eCheck digit schemeoptional · one of a setnot honoured by zpl.tools

Which check digits MSI appends. The schemes encode different data. A wrong scheme makes the renderer draw a symbol that scans to the wrong value.

Default
B
Invalid value
discarded, and the default applies. The parser expects Y or N here. The parser reports every other value as an invalid argument. The parser rejects all four documented values.
Test coverage
No documented value is exercised by a test (A, B, C, D). The invalid-value rule is not pinned by a test.
A
No check digit
B
One mod-10 check digit (default)
C
Two mod-10 check digits
D
A mod-11 digit followed by a mod-10 digit
hBar code heightoptional · dots

Height of the bars, without the interpretation line.

Default
the height set by ^BY, which itself defaults to 10 dots
Accepted range
1 to 32000 dots
Invalid value
clamped to the nearest allowed value. We measured this against live Labelary on 2026-07-12. The renderer clamps an out-of-range value to the violated bound, and does not ignore it.
Test coverage
Bounds pinned: below the minimum (0), above the maximum (33000). No test at the minimum or maximum. The invalid-value rule is not pinned by a test.
fPrint interpretation lineoptional · Y or N

Whether the renderer prints the interpretation line.

Default
Y
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and uses the default.
Test coverage
No documented value is exercised by a test (Y, N). The invalid-value rule is not pinned by a test.
Y
Print the text (default)
N
Print the symbol only
gInterpretation line aboveoptional · Y or N

Where the interpretation line sits. It has no effect without that line.

Default
N
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and uses the default.
Test coverage
No documented value is exercised by a test (Y, N). The invalid-value rule is not pinned by a test.
Y
Above the symbol
N
Below the symbol (default)
e2Show check digitoptional · Y or Nnot honoured by zpl.tools

Whether the computed check digit appears in the interpretation line. The renderer always encodes the check digit.

Default
N
Invalid value
discarded, and the default applies. The renderer does not parse this argument today. A value here has no effect.
Test coverage
No documented value is exercised by a test (Y, N). The invalid-value rule is not pinned by a test.
Y
Show it
N
Hide it (default)

Behavior

The character set is the ten digits. Each character is eight elements, four bars and four adjacent spaces. MSI is not self-checking, so the check-digit scheme is important.

The guide ties the maximum payload to the scheme. The payload is 1 to 14 digits with scheme B, C or D, and 1 to 13 digits with scheme A. A quiet zone is additional.

The printer always encodes the computed check digit, and the sixth argument only decides whether the digit also appears in the interpretation line. We measured this against Labelary on 2026-07-30. ^FD1234567 with the default mod-10 scheme and that argument set to Y prints 12345674.

MSI is a two-width symbology, so the ^BY ratio applies over the guide's range of 2.0:1 to 3.0:1.

The renderer parses ^BM and draws no symbol. It reports a diagnostic and does not default to a text run. Two parsing gaps go with that state. The parser reads the check-digit scheme as a Y/N flag and reports all four of A to D as invalid arguments, and it does not read the sixth argument. The renderer release fixes both gaps.

Tested behavior

Differences from the specification

zpl.tools against the ZPL II guide

Where our renderer behaves differently from the specification.

  • The guide takes the default orientation from ^FW. The renderer applies ^FW to text fields only. A barcode after ^FWR prints unrotated unless its own o argument rotates it. — not pinned by a test

Example

The default single mod-10 check digit, shown in the interpretation line:

^XA
^FO50,50^BY3
^BMN,B,80,Y,N,Y
^FD1234567^FS
^XZ

Open in viewer