Command and Attribute Format

Printing commands and attributes may be specified in a file, a string, or a JavaScript object. Regardless of the form, the contents must be in compliance with the JSON (JavaScript Object Notation) format.

In addition to meeting the restrictions specified for the JSON standard (www.json.org), printing commands and attributes should also follow the layout described here.

All settings intended for the Printing API must be contained within the LINEPRINTERCONTROL object, which contains the following required and optional members in this order:

"FormatVersion" : "1.0.0.0"

Following these basic format rules, a generic Command and Attribute JSON would look something like this:

{
"LINEPRINTERCONTROL" : {
    "FormatVersion" : "1.0.0.0",
    "DEFAULTS" : {
        "BoolSetting" : true, "NumSetting" : 42, "StringSetting" : "Default"
    },
    "PRINTERS" : {
        "Printer1" : { "PrinterNumber" : 1, "StringSetting" : "Uno" },
        "Printer2" : { "PrinterNumber" : 2, "StringSetting" : "Dos" }
    }
}
}

Add Comments

Any name/value pair whose name begins with "COMMENT" is ignored. These string values are only intended to improve the readability, and should never contain actual printer settings. Based on this rule, the following LINEPRINTERCONTROL object is functionally identical to the one in the previous example:

{
"LINEPRINTERCONTROL" : {
"FormatVersion" : "1.0.0.0",
"DEFAULTS" : {
"COMMENT" : "These values are used by every printer unless overridden.",
"BoolSetting" : true, "NumSetting" : 42, "StringSetting" : "Default"
},
"PRINTERS" : {
"COMMENT" : "Separate entries for each printer model.",
"Printer1" : { "PrinterNumber" : 1, "StringSetting" : "Uno" },
"Printer2" : { "PrinterNumber" : 2, "StringSetting" : "Dos" }
}
}
}

Share Common Settings

Any name/value pair whose name begins with "INCLUDE" indicates an additional settings section to be included. The string value (or array of string values) associated with the name should match a separate object that appears later in the LINEPRINTERCONTROL object.

This rule allows multiple printers to share the same settings where appropriate. In the following simplified example, the INCLUDE member allows multiple printers to share the same Boolean setting values:

{
"LINEPRINTERCONTROL" : {
"FormatVersion" : "1.0.0.0",
"DEFAULTS" : {
"BoolSetting" : true, "NumSetting" : 42, "StringSetting" : "Default"
},
"PRINTERS" : {
"Printer1" : { "INCLUDE" : "NumberedPrinter", "StringSetting" : "Uno" },
"Printer2" : { "INCLUDE" : "NumberedPrinter", "StringSetting" : "Dos" },
"PrinterA" : { "INCLUDE" : "LetteredPrinter", "StringSetting" : "Alpha" },
"NumberedPrinter" : { "HasNumberInName" : true, "HasLetterInName" : false },
"LetteredPrinter" : { "HasNumberInName" : false, "HasLetterInName" : true }
}
}
}

Based on this example, Printer1 and Printer2 would support settings for NumberedPrinter while PrinterA would not. This feature provides a convenient method of sharing settings across the same family of printer models.

The Printing API also supports multiple INCLUDE items in the same object. One way to do this is through the use of multiple INCLUDE_x members where x is a different number to distinguish the member names. The other method involves the use of an INCLUDE member with an array of string values as illustrated below:

{
"LINEPRINTERCONTROL" : {
"FormatVersion" : "1.0.0.0",
"DEFAULTS" : {
"BoolSetting" : true, "NumSetting" : 42, "StringSetting" : "Default"
},
"PRINTERS" : {
"Printer1" : { "INCLUDE" : "Feature1", "PrinterCode" : 1 },
"Printer2" : { "INCLUDE" : "Feature2", "PrinterCode" : 2 },
"Printer3" : { "INCLUDE_1" : "Feature1", "INCLUDE_2" : "Feature2", "PrinterCode" : 3 },
"Printer4" : { "INCLUDE" : [ "Feature1", "Feature2" ], "PrinterCode" : 4 },
"Feature1" : { "EnableFeature1" : true },
"Feature2" : { "EnableFeature2" : true }
}
}
}

An object referenced by an INCLUDE or INCLUDE_x member can also include other objects. In this example, the Printer1 object includes the Feature1 object, which in turn includes the SubFeature1 object:

{
"LINEPRINTERCONTROL" : {
"FormatVersion" : "1.0.0.0",
"DEFAULTS" : {
"BoolSetting" : true, "NumSetting" : 42, "StringSetting" : "Default"
},
"PRINTERS" : {
"Printer1" : { "INCLUDE" : "Feature1", "StringSetting" : "Uno" },
"Printer2" : { "INCLUDE" : "Feature2", "StringSetting" : "Dos" },
"Feature1" : { "INCLUDE" : "SubFeature1", "EnableFeature1" : true },
"SubFeature1" : { "EnableSubFeature1" : true },
"Feature2" : { "EnableFeature2" : true }
}
}
}

While the INCLUDE feature is a powerful tool, there are some limitations to what it can do:

Resolve Duplicate Setting Values

Speaking of duplicate values, the Printing API follows a fairly straightforward precedence rule for determining which values to store and which values to ignore. Basically, the first occurrence of a printer setting member found outside the DEFAULTS object defines the value. If a specific printer setting is not found outside the DEFAULTS section, then the default value is used instead. The following example illustrates this in better detail:

{
"LINEPRINTERCONTROL" : {
"FormatVersion" : "1.0.0.0",
"DEFAULTS" : {
"NumSetting" : 1, "StringSetting" : "Default"
},
"PRINTERS" : {
"Printer1" : { "StringSetting" : "Uno" },
"Printer2" : { "INCLUDE" : "ExtraSetting", "NumSetting" : 2, "StringSetting" : "Dos" },
"Printer3" : { "INCLUDE" : "ExtraSetting", "NumSetting" : 3 },
"ExtraSetting" : { "StringSetting" : "Tres" }
}
}
}

In this example, it contains entries to support three different printer models ("Printer1", "Printer2", and "Printer3") and each model has two settings ("NumSetting" and "StringSetting"). The setting values are:

Printer NumSetting StringSetting
Printer1 1 Uno
Printer2 2 Dos
Printer3 3 Tres

The Printer1 object demonstrates the two simplest cases. It doesn’t specify a NumSetting value, so it simply inherits a value of 1 from the DEFAULTS object. Conversely, it does specify a StringSetting value of "Uno", which overrides the value of "Default" from the DEFAULTS object.

The Printer2 object illustrates how only the first occurrence of a value is used. In this case, the StringSetting value of "Dos" overrides the value of "Default" from the DEFAULTS object. However, by the time the ExtraSetting object is parsed, a non-default StringSetting value has already been found. As a result, the parser discards the "Tres" value.

The Printer3 object demonstrates that the ExtraSetting object can override the "Default" value, but only because the Printer3 object itself doesn’t specify the StringSetting value directly.

Specify an Array of Bytes

According to the JSON standard, an array of bytes would be specified by an array of numerical values. While this notation is still supported, the Printing API also allows applications to specify a byte array via a simple string value. When it detects the array bracket characters ‘[‘ and ‘]’ inside a string, the JSON parser will automatically translate the string into a series of bytes. The following example demonstrates several different ways to specify a simple escape sequence:

{
"LINEPRINTERCONTROL" : {
"FormatVersion" : "1.0.0.0",
"DEFAULTS" : {
"BoolSetting" : true, "NumSetting" : 42, "StringSetting" : "Default"
},
"PRINTERS" : {
"COMMENT" : "All of these printers have the same ByteSetting value",
"Printer1" : { "ByteSetting" : [ 27, 119, 33, 0 ] },
"Printer2" : { "ByteSetting" : "[0x1b,w,!,0x00]" },
"Printer3" : { "ByteSetting" : "[0x1bw!0x00]" },
"Printer4" : { "ByteSetting" : "[\u001bw!\u0000]" },
"Printer5" : { "ByteSetting" : "[\u001b,w,!,\u0000]" }
}
}
}

The Printer1 object uses the standard JSON array of number values method, while the remaining objects use the special string processing functionality.

The Printer2 object uses the legacy method of specifying hexadecimal values using "0x" followed by two hex digits. This matches the format used in the .NET LinePrinter configuration file. The Printer3 object uses the same notation, but omits the comma separators.

The Printer5 object uses the JSON escape sequence for hexadecimal characters (\u followed by four hex digits) to specify the byte values. And the Printer4 object uses the same escape sequence but omits the comma separators.

There are several important rules to follow when using special byte array character strings:

Label Printing Commands and Attributes

The Printing API supports both receipt printing and label printing via the same LINEPRINTERCONTROL JSON object although the settings in the DEFAULTS object mostly target receipt printing. The label printing commands and attributes follow similar rules described in the previous sections.

Label Printer Entries

The label printer entries are defined in the PRINTERS object like the receipt printers. You should override the Initialize and NormalFont settings for label printer entries as shown below:

"PRINTERS":
{
"PB22_Fingerprint":
{
"DisplayName":"PB22 Bt Label Printer",
"Initialize": [], "NormalFont": []
}
}

The Printing API sends the Initialize commands followed by the NormalFont commands to the printer after a connection is successfully established. Unless these settings are overridden, the ESC/P commands defined for Initialize and NormalFont in the DEFAULTS object are sent. This may not work well with label printers. In the above example, both Initialize and NormalFont settings were set to an empty array so no commands are sent after the printer connection is opened. You may customize these settings if you wish to initialize the printer with specific printer commands.

Label Definitions

To print labels, you also need to define the commands to instruct the printer to print the label with a certain layout. The Printing API supports both raw label data stream and storing and invoking a label format on the printer. It also supports variable substitutions in the data stream or label format.

The label definitions are defined in the LABELS object in groups. Each label group is an object whose name identifies the group. In the following example, the LABELS object contains one group identified by the name of "2in_FingerprintLabels". This group contains two label definition objects, ItemLabel and URL_QRLabel.

"LABELS":
{
"2in_FingerprintLabels":
{
"ItemLabel":
{
"LabelDataStream": "DIR 4:AN 7:PP 30, 120:FT \"Swiss 721 Bold Condensed BT\",16:PT \"ItemName$$\":PP 120,75:BARSET \"CODE128\",3,1,4,150:PB \"ItemNo$$\":PP 280, 260:FT \"Letter Gothic 12 Pitch BT\",14:PT \"ItemNo$$\":PF\r\n",
"VarPostfix": "$$"
},
"URL_QRLabel":
{
"StoreFormat": "INPUT ON\r\nLAYOUT INPUT \"URLQRLABEL.LAY\"\r\nDIR 4:AN 7:PP 100, 20:FT \"Swiss 721 Bold Condensed BT\",16:PT VAR1$:PP 200, 20:FT \"Letter Gothic 12 Pitch BT\",14:PT VAR2$:PP 70,450:BARSET \"QRCODE\",1,1,8,2,2:PB VAR3$\r\nLAYOUT END\r\nINPUT OFF\r\n",
"InvokeFormat": "INPUT OFF\r\nFORMAT INPUT \"#\",\"@\",\"|\"\r\nINPUT ON\r\nLAYOUT RUN \"URLQRLABEL.LAY\"\r\n#qTextLine1$|qTextLine2$|qURL$|@\r\nPF\r\nINPUT OFF\r\n",
"VarPrefix": "q",
"VarPostfix": "$"
}
}
}

The label definition object may contain one or more of the following members:

Each label definition object needs to contain either a LabelDataStream member or an InvokeFormat member. If both members are specified, the Printing API only uses the LabelDataStream member.

The Printing API will substitute the variables defined in the LabelDataStream and the InvokeFormat members with the data specified in the API method. A complete variable name includes the VarPrefix and the VarPostfix values. For instance, the "qURL$" variable name specified in the InvokeFormat above starts with "q" (VarPrefix) and ends with "$" (VarPostfix). The purpose of the prefix and postfix is to distinguish the variable name from other printer commands.

The Printing API method takes key-value pairs for the variable substitutions where each key specifies the variable name (without prefix and suffix) and the key value specifies the data to replace the variable with. The Printing API will form the complete variable name based on the VarPrefix and VarPostfix settings. For more information, please refer to the language specific API documentation.

Include Label Groups in Printer Settings

You may use the LABEL_x member to include a label group to the printer settings, where x is a number to make the member name unique. For instance, the following example includes the 2in_FingerprintLabels label group. Now the application can use the Printing API to print either the ItemLabel or the URL_QRLabel to a printer using the PB22_Fingerprint settings.

"PRINTERS":
{
"PB22_Fingerprint":
{
"DisplayName":"PB22 Bt Label Printer",
"LABEL_01": "2in_FingerprintLabels",
"Initialize": [], "NormalFont": []
}
}